Alan Olsen | 494a43b | 2010-04-26 10:50:19 -0700 | [diff] [blame] | 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 | #ifndef _FLASH_INTERFACE_ |
| 21 | #define _FLASH_INTERFACE_ |
| 22 | |
| 23 | #include "ffsport.h" |
| 24 | #include "spectraswconfig.h" |
| 25 | |
| 26 | #define MAX_BYTE_VALUE 0xFF |
| 27 | #define MAX_WORD_VALUE 0xFFFF |
| 28 | #define MAX_U32_VALUE 0xFFFFFFFF |
| 29 | |
| 30 | #define MAX_BLOCKNODE_VALUE 0xFFFFFF |
| 31 | #define DISCARD_BLOCK 0x800000 |
| 32 | #define SPARE_BLOCK 0x400000 |
| 33 | #define BAD_BLOCK 0xC00000 |
| 34 | |
| 35 | #define UNHIT_CACHE_ITEM 0xFFFF |
| 36 | |
| 37 | #define NAND_CACHE_INIT_ADDR 0xffffffffffffffffULL |
| 38 | |
| 39 | #define IN_PROGRESS_BLOCK_TABLE 0x00 |
| 40 | #define CURRENT_BLOCK_TABLE 0x01 |
| 41 | |
| 42 | #define BTSIG_OFFSET (0) |
| 43 | #define BTSIG_BYTES (5) |
| 44 | #define BTSIG_DELTA (3) |
| 45 | |
| 46 | #define MAX_READ_COUNTER 0x2710 |
| 47 | |
| 48 | #define FIRST_BT_ID (1) |
| 49 | #define LAST_BT_ID (254) |
| 50 | #define BTBLOCK_INVAL (u32)(0xFFFFFFFF) |
| 51 | |
| 52 | struct device_info_tag { |
| 53 | u16 wDeviceMaker; |
| 54 | u16 wDeviceID; |
| 55 | u32 wDeviceType; |
| 56 | u32 wSpectraStartBlock; |
| 57 | u32 wSpectraEndBlock; |
| 58 | u32 wTotalBlocks; |
| 59 | u16 wPagesPerBlock; |
| 60 | u16 wPageSize; |
| 61 | u16 wPageDataSize; |
| 62 | u16 wPageSpareSize; |
| 63 | u16 wNumPageSpareFlag; |
| 64 | u16 wECCBytesPerSector; |
| 65 | u32 wBlockSize; |
| 66 | u32 wBlockDataSize; |
| 67 | u32 wDataBlockNum; |
| 68 | u8 bPlaneNum; |
| 69 | u16 wDeviceMainAreaSize; |
| 70 | u16 wDeviceSpareAreaSize; |
| 71 | u16 wDevicesConnected; |
| 72 | u16 wDeviceWidth; |
| 73 | u16 wHWRevision; |
| 74 | u16 wHWFeatures; |
| 75 | |
| 76 | u16 wONFIDevFeatures; |
| 77 | u16 wONFIOptCommands; |
| 78 | u16 wONFITimingMode; |
| 79 | u16 wONFIPgmCacheTimingMode; |
| 80 | |
| 81 | u16 MLCDevice; |
| 82 | u16 wSpareSkipBytes; |
| 83 | |
| 84 | u8 nBitsInPageNumber; |
| 85 | u8 nBitsInPageDataSize; |
| 86 | u8 nBitsInBlockDataSize; |
| 87 | }; |
| 88 | |
| 89 | extern struct device_info_tag DeviceInfo; |
| 90 | |
| 91 | /* Cache item format */ |
| 92 | struct flash_cache_item_tag { |
| 93 | u64 address; |
| 94 | u16 use_cnt; |
| 95 | u16 changed; |
| 96 | u8 *buf; |
| 97 | }; |
| 98 | |
| 99 | struct flash_cache_tag { |
| 100 | u32 cache_item_size; /* Size in bytes of each cache item */ |
| 101 | u16 pages_per_item; /* How many NAND pages in each cache item */ |
| 102 | u16 LRU; /* No. of the least recently used cache item */ |
| 103 | struct flash_cache_item_tag array[CACHE_ITEM_NUM]; |
| 104 | }; |
| 105 | |
| 106 | /* |
| 107 | *Data structure for each list node of the managment table |
| 108 | * used for the Level 2 Cache. Each node maps one logical NAND block. |
| 109 | */ |
| 110 | struct spectra_l2_cache_list { |
| 111 | struct list_head list; |
| 112 | u32 logical_blk_num; /* Logical block number */ |
| 113 | u32 pages_array[]; /* Page map array of this logical block. |
| 114 | * Array index is the logical block number, |
| 115 | * and for every item of this arry: |
| 116 | * high 16 bit is index of the L2 cache block num, |
| 117 | * low 16 bit is the phy page num |
| 118 | * of the above L2 cache block. |
| 119 | * This array will be kmalloc during run time. |
| 120 | */ |
| 121 | }; |
| 122 | |
| 123 | struct spectra_l2_cache_info { |
| 124 | u32 blk_array[BLK_NUM_FOR_L2_CACHE]; |
| 125 | u16 cur_blk_idx; /* idx to the phy block number of current using */ |
| 126 | u16 cur_page_num; /* pages number of current using */ |
| 127 | struct spectra_l2_cache_list table; /* First node of the table */ |
| 128 | }; |
| 129 | |
| 130 | #define RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE 1 |
| 131 | |
| 132 | #if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE |
| 133 | struct flash_cache_mod_item_tag { |
| 134 | u64 address; |
| 135 | u8 changed; |
| 136 | }; |
| 137 | |
| 138 | struct flash_cache_delta_list_tag { |
| 139 | u8 item; /* used cache item */ |
| 140 | struct flash_cache_mod_item_tag cache; |
| 141 | }; |
| 142 | #endif |
| 143 | |
| 144 | extern struct flash_cache_tag Cache; |
| 145 | |
| 146 | extern u8 *buf_read_page_main_spare; |
| 147 | extern u8 *buf_write_page_main_spare; |
| 148 | extern u8 *buf_read_page_spare; |
| 149 | extern u8 *buf_get_bad_block; |
| 150 | extern u8 *cdma_desc_buf; |
| 151 | extern u8 *memcp_desc_buf; |
| 152 | |
| 153 | /* struture used for IndentfyDevice function */ |
| 154 | struct spectra_indentfy_dev_tag { |
| 155 | u32 NumBlocks; |
| 156 | u16 PagesPerBlock; |
| 157 | u16 PageDataSize; |
| 158 | u16 wECCBytesPerSector; |
| 159 | u32 wDataBlockNum; |
| 160 | }; |
| 161 | |
| 162 | int GLOB_FTL_Flash_Init(void); |
| 163 | int GLOB_FTL_Flash_Release(void); |
| 164 | /*void GLOB_FTL_Erase_Flash(void);*/ |
| 165 | int GLOB_FTL_Block_Erase(u64 block_addr); |
| 166 | int GLOB_FTL_Is_BadBlock(u32 block_num); |
| 167 | int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data); |
| 168 | int GLOB_FTL_Event_Status(int *); |
| 169 | u16 glob_ftl_execute_cmds(void); |
| 170 | |
| 171 | /*int FTL_Read_Disturbance(ADDRESSTYPE dwBlockAddr);*/ |
| 172 | int FTL_Read_Disturbance(u32 dwBlockAddr); |
| 173 | |
| 174 | /*Flash r/w based on cache*/ |
| 175 | int GLOB_FTL_Page_Read(u8 *read_data, u64 page_addr); |
| 176 | int GLOB_FTL_Page_Write(u8 *write_data, u64 page_addr); |
| 177 | int GLOB_FTL_Wear_Leveling(void); |
| 178 | int GLOB_FTL_Flash_Format(void); |
| 179 | int GLOB_FTL_Init(void); |
| 180 | int GLOB_FTL_Flush_Cache(void); |
| 181 | int GLOB_FTL_Garbage_Collection(void); |
| 182 | int GLOB_FTL_BT_Garbage_Collection(void); |
| 183 | void GLOB_FTL_Cache_Release(void); |
| 184 | u8 *get_blk_table_start_addr(void); |
| 185 | u8 *get_wear_leveling_table_start_addr(void); |
| 186 | unsigned long get_blk_table_len(void); |
| 187 | unsigned long get_wear_leveling_table_len(void); |
| 188 | |
| 189 | #if DEBUG_BNDRY |
| 190 | void debug_boundary_lineno_error(int chnl, int limit, int no, int lineno, |
| 191 | char *filename); |
| 192 | #define debug_boundary_error(chnl, limit, no) debug_boundary_lineno_error(chnl,\ |
| 193 | limit, no, __LINE__, __FILE__) |
| 194 | #else |
| 195 | #define debug_boundary_error(chnl, limit, no) ; |
| 196 | #endif |
| 197 | |
| 198 | #endif /*_FLASH_INTERFACE_*/ |