/drivers/block/sun3i_nand/src/physic/nand_simple_r.c
C | 695 lines | 432 code | 117 blank | 146 comment | 77 complexity | 6a80b1bfad05ca458a59a1f196e6f46e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* 2 * drivers/block/sun3i_nand/src/physic/nand_simple_r.c 3 * 4 * (C) Copyright 2007-2012 5 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23#include "../include/nand_type.h" 24#include "../include/nand_physic.h" 25#include "../include/nand_simple.h" 26#include "../../nfc/nfc.h" 27 28#include <linux/io.h> 29 30struct __NandStorageInfo_t NandStorageInfo; 31struct __NandPageCachePool_t PageCachePool; 32void __iomem *nand_base; 33 34/************************************************************************** 35************************* add one cmd to cmd list****************************** 36****************************************************************************/ 37void _add_cmd_list(NFC_CMD_LIST *cmd,__u32 value,__u32 addr_cycle,__u8 *addr,__u8 data_fetch_flag, 38 __u8 main_data_fetch,__u32 bytecnt,__u8 wait_rb_flag) 39{ 40 cmd->addr = addr; 41 cmd->addr_cycle = addr_cycle; 42 cmd->data_fetch_flag = data_fetch_flag; 43 cmd->main_data_fetch = main_data_fetch; 44 cmd->bytecnt = bytecnt; 45 cmd->value = value; 46 cmd->wait_rb_flag = wait_rb_flag; 47 cmd->next = NULL; 48} 49 50/**************************************************************************** 51*********************translate (block + page+ sector) into 5 bytes addr*************** 52*****************************************************************************/ 53void _cal_addr_in_chip(__u32 block, __u32 page, __u32 sector,__u8 *addr, __u8 cycle) 54{ 55 __u32 row; 56 __u32 column; 57 58 column = 512 * sector; 59 row = block * PAGE_CNT_OF_PHY_BLK + page; 60 61 switch(cycle){ 62 case 1: 63 addr[0] = 0x00; 64 break; 65 case 2: 66 addr[0] = column & 0xff; 67 addr[1] = (column >> 8) & 0xff; 68 break; 69 case 3: 70 addr[0] = row & 0xff; 71 addr[1] = (row >> 8) & 0xff; 72 addr[2] = (row >> 16) & 0xff; 73 break; 74 case 4: 75 addr[0] = column && 0xff; 76 addr[1] = (column >> 8) & 0xff; 77 addr[2] = row & 0xff; 78 addr[3] = (row >> 8) & 0xff; 79 break; 80 case 5: 81 addr[0] = column & 0xff; 82 addr[1] = (column >> 8) & 0xff; 83 addr[2] = row & 0xff; 84 addr[3] = (row >> 8) & 0xff; 85 addr[4] = (row >> 16) & 0xff; 86 break; 87 default: 88 break; 89 } 90 91} 92 93 94 95#if 0 96__u8 _cal_real_chip(__u32 global_bank) 97{ 98 __u8 chip; 99 __u8 i,cnt; 100 101 cnt = 0; 102 chip = global_bank / BNK_CNT_OF_CHIP; 103 104 for (i = 0; i <MAX_CHIP_SELECT_CNT; i++ ){ 105 if (CHIP_CONNECT_INFO & (1 << i)) { 106 cnt++; 107 if (cnt == (chip+1)){ 108 chip = i; 109 return chip; 110 } 111 } 112 } 113 114 PHY_ERR("wrong chip number ,chip = %d, chip info = %x\n",chip,CHIP_CONNECT_INFO); 115 116 return 0xff; 117} 118#endif 119 120__u8 _cal_real_chip(__u32 global_bank) 121{ 122 __u8 chip = 0; 123 124 if((RB_CONNECT_MODE == 0)&&(global_bank<=2)) 125 { 126 if(global_bank) 127 chip = 7; 128 else 129 chip = 0; 130 131 return chip; 132 } 133 if((RB_CONNECT_MODE == 1)&&(global_bank<=1)) 134 { 135 chip = global_bank; 136 return chip; 137 } 138 if((RB_CONNECT_MODE == 2)&&(global_bank<=2)) 139 { 140 chip = global_bank; 141 return chip; 142 } 143 if((RB_CONNECT_MODE == 3)&&(global_bank<=2)) 144 { 145 chip = global_bank*2; 146 return chip; 147 } 148 if((RB_CONNECT_MODE == 4)&&(global_bank<=4)) 149 { 150 switch(global_bank){ 151 case 0: 152 chip = 0; 153 break; 154 case 1: 155 chip = 2; 156 break; 157 case 2: 158 chip = 1; 159 break; 160 case 3: 161 chip = 3; 162 break; 163 default : 164 chip =0; 165 } 166 167 return chip; 168 } 169 if((RB_CONNECT_MODE == 5)&&(global_bank<=4)) 170 { 171 chip = global_bank*2; 172 173 return chip; 174 } 175 if((RB_CONNECT_MODE == 8)&&(global_bank<=8)) 176 { 177 switch(global_bank){ 178 case 0: 179 chip = 0; 180 break; 181 case 1: 182 chip = 2; 183 break; 184 case 2: 185 chip = 1; 186 break; 187 case 3: 188 chip = 3; 189 break; 190 case 4: 191 chip = 4; 192 break; 193 case 5: 194 chip = 6; 195 break; 196 case 6: 197 chip = 5; 198 break; 199 case 7: 200 chip = 7; 201 break; 202 default : chip =0; 203 204 } 205 206 return chip; 207 } 208 209 //dump_stack(); 210 PHY_ERR("wrong chip number ,rb_mode = %d, bank = %d, chip = %d, chip info = %x\n",RB_CONNECT_MODE, global_bank, chip, CHIP_CONNECT_INFO); 211 212 return 0xff; 213} 214 215__u8 _cal_real_rb(__u32 chip) 216{ 217 __u8 rb; 218 219 220 rb = 0; 221 222 if(RB_CONNECT_MODE == 0) 223 { 224 rb = 0; 225 } 226 if(RB_CONNECT_MODE == 1) 227 { 228 rb = chip; 229 } 230 if(RB_CONNECT_MODE == 2) 231 { 232 rb = chip; 233 } 234 if(RB_CONNECT_MODE == 3) 235 { 236 rb = chip/2; 237 } 238 if(RB_CONNECT_MODE == 4) 239 { 240 rb = chip/2; 241 } 242 if(RB_CONNECT_MODE == 5) 243 { 244 rb = (chip/2)%2; 245 } 246 if(RB_CONNECT_MODE == 8) 247 { 248 rb = (chip/2)%2; 249 } 250 251 if((rb!=0)&&(rb!=1)) 252 { 253 PHY_ERR("wrong Rb connect Mode ,chip = %d, RbConnectMode = %d \n",chip,RB_CONNECT_MODE); 254 return 0xff; 255 } 256 257 return rb; 258} 259 260/******************************************************************* 261**********************get status************************************** 262********************************************************************/ 263__s32 _read_status(__u32 cmd_value, __u32 nBank) 264{ 265 /*get status*/ 266 __u8 addr[5]; 267 __u32 addr_cycle; 268 NFC_CMD_LIST cmd_list; 269 270 addr_cycle = 0; 271 272 if(!(cmd_value == 0x70 || cmd_value == 0x71)) 273 { 274 /* not 0x70 or 0x71, need send some address cycle */ 275 if(cmd_value == 0x78) 276 addr_cycle = 3; 277 else 278 addr_cycle = 1; 279 _cal_addr_in_chip(nBank*BLOCK_CNT_OF_DIE,0,0,addr,addr_cycle); 280 } 281 _add_cmd_list(&cmd_list, cmd_value, addr_cycle, addr, 1,NFC_IGNORE,1,NFC_IGNORE); 282 return (NFC_GetStatus(&cmd_list)); 283 284} 285 286/******************************************************************** 287***************************wait rb ready******************************* 288*********************************************************************/ 289__s32 _wait_rb_ready(__u32 chip) 290{ 291 __s32 timeout = 0xffff; 292 __u32 rb; 293 294 295 rb = _cal_real_rb(chip); 296 297 298 /*wait rb ready*/ 299 while((timeout--) && (NFC_CheckRbReady(rb))); 300 if (timeout < 0) 301 return -ERR_TIMEOUT; 302 303 return 0; 304} 305 306void _pending_dma_irq_sem(void) 307{ 308 return; 309} 310 311__s32 _read_single_page(struct boot_physical_param *readop,__u8 dma_wait_mode) 312{ 313 __s32 ret; 314 __u32 rb; 315 316 //__u8 *sparebuf; 317 __u8 sparebuf[4*16]; 318 __u8 addr[5]; 319 NFC_CMD_LIST cmd_list[4]; 320 __u32 list_len,i; 321 322 //sparebuf = (__u8 *)MALLOC(SECTOR_CNT_OF_SINGLE_PAGE * 4); 323 /*create cmd list*/ 324 /*samll block*/ 325 if (SECTOR_CNT_OF_SINGLE_PAGE == 1){ 326 _cal_addr_in_chip(readop->block,readop->page,0,addr,4); 327 _add_cmd_list(cmd_list,0x00,4,addr,NFC_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_WAIT_RB); 328 } 329 /*large block*/ 330 else{ 331 /*the cammand have no corresponding feature if IGNORE was set, */ 332 _cal_addr_in_chip(readop->block,readop->page,0,addr,5); 333 _add_cmd_list(cmd_list,0x00,5,addr,NFC_NO_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_NO_WAIT_RB); 334 335 } 336 _add_cmd_list(cmd_list + 1,0x05,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE); 337 _add_cmd_list(cmd_list + 2,0xe0,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE); 338 _add_cmd_list(cmd_list + 3,0x30,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE); 339 list_len = 4; 340 for(i = 0; i < list_len - 1; i++){ 341 cmd_list[i].next = &(cmd_list[i+1]); 342 } 343 344 /*wait rb ready*/ 345 ret = _wait_rb_ready(readop->chip); 346 if (ret) 347 return ret; 348 349 rb = _cal_real_rb(readop->chip); 350 NFC_SelectChip(readop->chip); 351 NFC_SelectRb(rb); 352 353 354 ret = NFC_Read(cmd_list, readop->mainbuf, sparebuf, dma_wait_mode , NFC_PAGE_MODE); 355 if (dma_wait_mode) 356 _pending_dma_irq_sem(); 357 358 if (readop->oobbuf){ 359 MEMCPY(readop->oobbuf,sparebuf, 2 * 4); 360 } 361 362 NFC_DeSelectChip(readop->chip); 363 NFC_DeSelectRb(rb); 364 365 //FREE(sparebuf); 366 return ret; 367} 368 369 370 371/* 372************************************************************************************************************************ 373* INIT NAND FLASH DRIVER PHYSICAL MODULE 374* 375* Description: init nand flash driver physical module. 376* 377* Aguments : none 378* 379* Returns : the resutl of initial. 380* = 0 initial successful; 381* = -1 initial failed. 382************************************************************************************************************************ 383*/ 384__s32 PHY_Init(void) 385{ 386 NFC_INIT_INFO nand_info; 387 nand_info.bus_width = 0x0; 388 nand_info.ce_ctl = 0x0; 389 nand_info.ce_ctl1 = 0x0; 390 nand_info.debug = 0x0; 391 nand_info.pagesize = 4; 392 nand_info.rb_sel = 1; 393 nand_info.serial_access_mode = 1; 394 395 //nand_base = ioremap(0x01C03000, 4096 ); 396 //modify by penggang for f20 linux 397 398// if (nand_base == NULL) { 399// printk(KERN_ERR "dma failed to remap register block\n"); 400// return -ENOMEM; 401// } 402 403 return (NFC_Init(&nand_info)); 404} 405 406__s32 PHY_ChangeMode(__u8 serial_mode) 407{ 408 409 NFC_INIT_INFO nand_info; 410 411 /*memory allocate*/ 412 if (!PageCachePool.PageCache0){ 413 PageCachePool.PageCache0 = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 512); 414 if (!PageCachePool.PageCache0) 415 return -1; 416 } 417 418 if (!PageCachePool.SpareCache){ 419 PageCachePool.SpareCache = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 4); 420 if (!PageCachePool.SpareCache) 421 return -1; 422 } 423 424 if (!PageCachePool.TmpPageCache){ 425 PageCachePool.TmpPageCache = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 512); 426 if (!PageCachePool.TmpPageCache) 427 return -1; 428 } 429 430 NFC_SetEccMode(ECC_MODE); 431 432 433 nand_info.bus_width = 0x0; 434 nand_info.ce_ctl = 0x0; 435 nand_info.ce_ctl1 = 0x0; 436 nand_info.debug = 0x0; 437 nand_info.pagesize = SECTOR_CNT_OF_SINGLE_PAGE; 438 439 440 nand_info.serial_access_mode = serial_mode; 441 return (NFC_ChangMode(&nand_info)); 442} 443 444 445/* 446************************************************************************************************************************ 447* NAND FLASH DRIVER PHYSICAL MODULE EXIT 448* 449* Description: nand flash driver physical module exit. 450* 451* Aguments : none 452* 453* Returns : the resutl of exit. 454* = 0 exit successful; 455* = -1 exit failed. 456************************************************************************************************************************ 457*/ 458__s32 PHY_Exit(void) 459{ 460 461 if (PageCachePool.PageCache0){ 462 FREE(PageCachePool.PageCache0,SECTOR_CNT_OF_SUPER_PAGE * 512); 463 PageCachePool.PageCache0 = NULL; 464 } 465 if (PageCachePool.SpareCache){ 466 FREE(PageCachePool.SpareCache,SECTOR_CNT_OF_SUPER_PAGE * 4); 467 PageCachePool.SpareCache = NULL; 468 } 469 if (PageCachePool.TmpPageCache){ 470 FREE(PageCachePool.TmpPageCache,SECTOR_CNT_OF_SUPER_PAGE * 512); 471 PageCachePool.TmpPageCache = NULL; 472 } 473 474 NFC_Exit(); 475 return 0; 476} 477 478 479/* 480************************************************************************************************************************ 481* RESET ONE NAND FLASH CHIP 482* 483*Description: Reset the given nand chip; 484* 485*Arguments : nChip the chip select number, which need be reset. 486* 487*Return : the result of chip reset; 488* = 0 reset nand chip successful; 489* = -1 reset nand chip failed. 490************************************************************************************************************************ 491*/ 492__s32 PHY_ResetChip(__u32 nChip) 493{ 494 __s32 ret; 495 __s32 timeout = 0xffff; 496 497 498 NFC_CMD_LIST cmd; 499 500 NFC_SelectChip(nChip); 501 502 _add_cmd_list(&cmd, 0xff, 0 , NFC_IGNORE, NFC_NO_DATA_FETCH, NFC_IGNORE, NFC_IGNORE, NFC_NO_WAIT_RB); 503 ret = NFC_ResetChip(&cmd); 504 505 /*wait rb0 ready*/ 506 NFC_SelectRb(0); 507 while((timeout--) && (NFC_CheckRbReady(0))); 508 if (timeout < 0) 509 return -ERR_TIMEOUT; 510 511 /*wait rb0 ready*/ 512 NFC_SelectRb(1); 513 while((timeout--) && (NFC_CheckRbReady(1))); 514 if (timeout < 0) 515 return -ERR_TIMEOUT; 516 517 NFC_DeSelectChip(nChip); 518 519 520 521 return ret; 522} 523 524 525/* 526************************************************************************************************************************ 527* READ NAND FLASH ID 528* 529*Description: Read nand flash ID from the given nand chip. 530* 531*Arguments : nChip the chip number whoes ID need be read; 532* pChipID the po__s32er to the chip ID buffer. 533* 534*Return : read nand chip ID result; 535* = 0 read chip ID successful, the chip ID has been stored in given buffer; 536* = -1 read chip ID failed. 537************************************************************************************************************************ 538*/ 539 540__s32 PHY_ReadNandId(__s32 nChip, void *pChipID) 541{ 542 __s32 ret; 543 544 545 NFC_CMD_LIST cmd; 546 __u8 addr = 0; 547 548 NFC_SelectChip(nChip); 549 550 _add_cmd_list(&cmd, 0x90,1 , &addr, NFC_DATA_FETCH, NFC_IGNORE, 5, NFC_NO_WAIT_RB); 551 ret = NFC_GetId(&cmd, pChipID); 552 553 NFC_DeSelectChip(nChip); 554 555 556 return ret; 557} 558 559/* 560************************************************************************************************************************ 561* CHECK WRITE PROTECT STATUS 562* 563*Description: check the status of write protect. 564* 565*Arguments : nChip the number of chip, which nand chip need be checked. 566* 567*Return : the result of status check; 568* = 0 the nand flash is not write proteced; 569* = 1 the nand flash is write proteced; 570* = -1 check status failed. 571************************************************************************************************************************ 572*/ 573__s32 PHY_CheckWp(__u32 nChip) 574{ 575 __s32 status; 576 __u32 rb; 577 578 579 rb = _cal_real_rb(nChip); 580 NFC_SelectChip(nChip); 581 NFC_SelectRb(rb); 582 583 584 status = _read_status(0x70,nChip); 585 NFC_DeSelectChip(nChip); 586 NFC_DeSelectRb(rb); 587 588 if (status < 0) 589 return status; 590 591 if (status & NAND_WRITE_PROTECT){ 592 return 1; 593 } 594 else 595 return 0; 596} 597 598void _pending_rb_irq_sem(void) 599{ 600 return; 601} 602 603void _do_irq(void) 604{ 605 606} 607 608 609__s32 PHY_SimpleRead (struct boot_physical_param *readop) 610{ 611 //if (_read_single_page(readop,0) < 0) 612 // return FAIL; 613 //return SUCESS; 614 return (_read_single_page(readop,0)); 615} 616 617/* 618************************************************************************************************************************ 619* SYNC NAND FLASH PHYSIC OPERATION 620* 621*Description: Sync nand flash operation, check nand flash program/erase operation status. 622* 623*Arguments : nBank the number of the bank which need be synchronized; 624* bMode the type of synch, 625* = 0 sync the chip which the bank belonged to, wait the whole chip 626* to be ready, and report status. if the chip support cacheprogram, 627* need check if the chip is true ready; 628* = 1 only sync the the bank, wait the bank ready and report the status, 629* if the chip support cache program, need not check if the cache is 630* true ready. 631* 632*Return : the result of synch; 633* = 0 synch nand flash successful, nand operation ok; 634* = -1 synch nand flash failed. 635************************************************************************************************************************ 636*/ 637__s32 PHY_SynchBank(__u32 nBank, __u32 bMode) 638{ 639 __s32 ret,status; 640 __u32 chip; 641 __u32 rb; 642 __u32 cmd_value; 643 __s32 timeout = 0xffff; 644 645 ret = 0; 646 /*get chip no*/ 647 chip = _cal_real_chip(nBank); 648 rb = _cal_real_rb(chip); 649 650 if (0xff == chip){ 651 PHY_ERR("PHY_SynchBank : beyond chip count\n"); 652 return -ERR_INVALIDPHYADDR; 653 } 654 655 if ( (bMode == 1) && SUPPORT_INT_INTERLEAVE){ 656 if (nBank%BNK_CNT_OF_CHIP == 0) 657 cmd_value = NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd; 658 else 659 cmd_value = NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd; 660 } 661 else{ 662 if (SUPPORT_MULTI_PROGRAM) 663 cmd_value = NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd; 664 else 665 cmd_value = 0x70; 666 } 667 668 /*if support rb irq , last op is erase or write*/ 669 if (SUPPORT_RB_IRQ) 670 _pending_rb_irq_sem(); 671 672 NFC_SelectChip(chip); 673 NFC_SelectRb(rb); 674 675 while(1){ 676 status = _read_status(cmd_value,nBank%BNK_CNT_OF_CHIP); 677 if (status < 0) 678 return status; 679 680 if (status & NAND_STATUS_READY) 681 break; 682 683 if (timeout-- < 0){ 684 PHY_ERR("PHY_SynchBank : wait nand ready timeout,chip = %x, bank = %x, cmd value = %x, status = %x\n",chip,nBank,cmd_value,status); 685 return -ERR_TIMEOUT; 686 } 687 } 688 if(status & NAND_OPERATE_FAIL) 689 ret = NAND_OP_FALSE; 690 NFC_DeSelectChip(chip); 691 NFC_DeSelectRb(rb); 692 693 694 return ret; 695}