summaryrefslogtreecommitdiff
path: root/drivers/staging/spectra/flash.h
blob: 5ed05805cf65f4003b9baa6462ad37b31f834399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * NAND Flash Controller Device Driver
 * Copyright (c) 2009, Intel Corporation and its suppliers.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef _FLASH_INTERFACE_
#define _FLASH_INTERFACE_

#include "ffsport.h"
#include "spectraswconfig.h"

#define MAX_BYTE_VALUE        0xFF
#define MAX_WORD_VALUE        0xFFFF
#define MAX_U32_VALUE        0xFFFFFFFF

#define MAX_BLOCKNODE_VALUE     0xFFFFFF
#define DISCARD_BLOCK           0x800000
#define SPARE_BLOCK             0x400000
#define BAD_BLOCK               0xC00000

#define UNHIT_CACHE_ITEM         0xFFFF

#define NAND_CACHE_INIT_ADDR    0xffffffffffffffffULL

#define IN_PROGRESS_BLOCK_TABLE   0x00
#define CURRENT_BLOCK_TABLE       0x01

#define BTSIG_OFFSET   (0)
#define BTSIG_BYTES    (5)
#define BTSIG_DELTA    (3)

#define MAX_READ_COUNTER  0x2710

#define FIRST_BT_ID		(1)
#define LAST_BT_ID    (254)
#define BTBLOCK_INVAL  (u32)(0xFFFFFFFF)

struct device_info_tag {
	u16 wDeviceMaker;
	u16 wDeviceID;
	u32 wDeviceType;
	u32 wSpectraStartBlock;
	u32 wSpectraEndBlock;
	u32 wTotalBlocks;
	u16 wPagesPerBlock;
	u16 wPageSize;
	u16 wPageDataSize;
	u16 wPageSpareSize;
	u16 wNumPageSpareFlag;
	u16 wECCBytesPerSector;
	u32 wBlockSize;
	u32 wBlockDataSize;
	u32 wDataBlockNum;
	u8 bPlaneNum;
	u16 wDeviceMainAreaSize;
	u16 wDeviceSpareAreaSize;
	u16 wDevicesConnected;
	u16 wDeviceWidth;
	u16 wHWRevision;
	u16 wHWFeatures;

	u16 wONFIDevFeatures;
	u16 wONFIOptCommands;
	u16 wONFITimingMode;
	u16 wONFIPgmCacheTimingMode;

	u16 MLCDevice;
	u16 wSpareSkipBytes;

	u8 nBitsInPageNumber;
	u8 nBitsInPageDataSize;
	u8 nBitsInBlockDataSize;
};

extern struct device_info_tag DeviceInfo;

/* Cache item format */
struct flash_cache_item_tag {
	u64 address;
	u16 use_cnt;
	u16 changed;
	u8 *buf;
};

struct flash_cache_tag {
	u32 cache_item_size; /* Size in bytes of each cache item */
	u16 pages_per_item; /* How many NAND pages in each cache item */
	u16 LRU; /* No. of the least recently used cache item */
	struct flash_cache_item_tag array[CACHE_ITEM_NUM];
};

/*
 *Data structure for each list node of the managment table
 * used for the Level 2 Cache. Each node maps one logical NAND block.
 */
struct spectra_l2_cache_list {
	struct list_head list;
	u32 logical_blk_num; /* Logical block number */
	u32 pages_array[]; /* Page map array of this logical block.
			   * Array index is the logical block number,
			   * and for every item of this arry:
			   * high 16 bit is index of the L2 cache block num,
			   * low 16 bit is the phy page num
			   * of the above L2 cache block.
			   * This array will be kmalloc during run time.
			   */
};

struct spectra_l2_cache_info {
	u32 blk_array[BLK_NUM_FOR_L2_CACHE];
	u16 cur_blk_idx; /* idx to the phy block number of current using */
	u16 cur_page_num; /* pages number of current using */
	struct spectra_l2_cache_list table; /* First node of the table */
};

#define RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE    1

#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
struct flash_cache_mod_item_tag {
	u64 address;
	u8 changed;
};

struct flash_cache_delta_list_tag {
	u8 item;  /* used cache item */
	struct flash_cache_mod_item_tag cache;
};
#endif

extern struct flash_cache_tag Cache;

extern u8 *buf_read_page_main_spare;
extern u8 *buf_write_page_main_spare;
extern u8 *buf_read_page_spare;
extern u8 *buf_get_bad_block;
extern u8 *cdma_desc_buf;
extern u8 *memcp_desc_buf;

/* struture used for IndentfyDevice function */
struct spectra_indentfy_dev_tag {
	u32 NumBlocks;
	u16 PagesPerBlock;
	u16 PageDataSize;
	u16 wECCBytesPerSector;
	u32 wDataBlockNum;
};

int GLOB_FTL_Flash_Init(void);
int GLOB_FTL_Flash_Release(void);
/*void GLOB_FTL_Erase_Flash(void);*/
int GLOB_FTL_Block_Erase(u64 block_addr);
int GLOB_FTL_Is_BadBlock(u32 block_num);
int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data);
int GLOB_FTL_Event_Status(int *);
u16 glob_ftl_execute_cmds(void);

/*int FTL_Read_Disturbance(ADDRESSTYPE dwBlockAddr);*/
int FTL_Read_Disturbance(u32 dwBlockAddr);

/*Flash r/w based on cache*/
int GLOB_FTL_Page_Read(u8 *read_data, u64 page_addr);
int GLOB_FTL_Page_Write(u8 *write_data, u64 page_addr);
int GLOB_FTL_Wear_Leveling(void);
int GLOB_FTL_Flash_Format(void);
int GLOB_FTL_Init(void);
int GLOB_FTL_Flush_Cache(void);
int GLOB_FTL_Garbage_Collection(void);
int GLOB_FTL_BT_Garbage_Collection(void);
void GLOB_FTL_Cache_Release(void);
u8 *get_blk_table_start_addr(void);
u8 *get_wear_leveling_table_start_addr(void);
unsigned long get_blk_table_len(void);
unsigned long get_wear_leveling_table_len(void);

#if DEBUG_BNDRY
void debug_boundary_lineno_error(int chnl, int limit, int no, int lineno,
				char *filename);
#define debug_boundary_error(chnl, limit, no) debug_boundary_lineno_error(chnl,\
						limit, no, __LINE__, __FILE__)
#else
#define debug_boundary_error(chnl, limit, no) ;
#endif

#endif /*_FLASH_INTERFACE_*/