blob: 3905c08d439000f64767973d8351dc54a47ba47a (
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
/*
* drv_sfc.h
*
* Created on: 2016��4��5��
* Author: Urey
*/
#ifndef DRIVER_DRV_SFC_H_
#define DRIVER_DRV_SFC_H_
#include <stdint.h>
#define SFC_USE_SWAP
#define SFC_USE_DMA
#define SFC_USE_QUAD
#define UNCACHE(addr) ((((uint32_t)(addr)) | 0xa0000000))
/* SFC register */
#define SFC_GLB (0x0000)
#define SFC_DEV_CONF (0x0004)
#define SFC_DEV_STA_EXP (0x0008)
#define SFC_DEV_STA_RT (0x000c)
#define SFC_DEV_STA_MSK (0x0010)
#define SFC_TRAN_CONF(n) (0x0014 + (n * 4))
#define SFC_TRAN_LEN (0x002c)
#define SFC_DEV_ADDR(n) (0x0030 + (n * 4))
#define SFC_DEV_ADDR_PLUS(n) (0x0048 + (n * 4))
#define SFC_MEM_ADDR (0x0060)
#define SFC_TRIG (0x0064)
#define SFC_SR (0x0068)
#define SFC_SCR (0x006c)
#define SFC_INTC (0x0070)
#define SFC_FSM (0x0074)
#define SFC_CGE (0x0078)
#define SFC_RM_DR (0x1000)
/* For SFC_GLB */
#define GLB_TRAN_DIR (1 << 13)
#define GLB_TRAN_DIR_WRITE (1)
#define GLB_TRAN_DIR_READ (0)
#define GLB_THRESHOLD_OFFSET (7)
#define GLB_THRESHOLD_MSK (0x3f << GLB_THRESHOLD_OFFSET)
#define GLB_OP_MODE (1 << 6)
#define SLAVE_MODE (0x0)
#define DMA_MODE (0x1)
#define GLB_PHASE_NUM_OFFSET (3)
#define GLB_PHASE_NUM_MSK (0x7 << GLB_PHASE_NUM_OFFSET)
#define GLB_WP_EN (1 << 2)
#define GLB_BURST_MD_OFFSET (0)
#define GLB_BURST_MD_MSK (0x3 << GLB_BURST_MD_OFFSET)
/* For SFC_DEV_CONF */
#define DEV_CONF_ONE_AND_HALF_CYCLE_DELAY (3)
#define DEV_CONF_ONE_CYCLE_DELAY (2)
#define DEV_CONF_HALF_CYCLE_DELAY (1)
#define DEV_CONF_NO_DELAY (0)
#define DEV_CONF_SMP_DELAY_OFFSET (16)
#define DEV_CONF_SMP_DELAY_MSK (0x3 << DEV_CONF_SMP_DELAY_OFFSET)
#define DEV_CONF_CMD_TYPE (0x1 << 15)
#define DEV_CONF_STA_TYPE_OFFSET (13)
#define DEV_CONF_STA_TYPE_MSK (0x1 << DEV_CONF_STA_TYPE_OFFSET)
#define DEV_CONF_THOLD_OFFSET (11)
#define DEV_CONF_THOLD_MSK (0x3 << DEV_CONF_THOLD_OFFSET)
#define DEV_CONF_TSETUP_OFFSET (9)
#define DEV_CONF_TSETUP_MSK (0x3 << DEV_CONF_TSETUP_OFFSET)
#define DEV_CONF_TSH_OFFSET (5)
#define DEV_CONF_TSH_MSK (0xf << DEV_CONF_TSH_OFFSET)
#define DEV_CONF_CPHA (0x1 << 4)
#define DEV_CONF_CPOL (0x1 << 3)
#define DEV_CONF_CEDL (0x1 << 2)
#define DEV_CONF_HOLDDL (0x1 << 1)
#define DEV_CONF_WPDL (0x1 << 0)
/* For SFC_TRAN_CONF */
#define TRAN_CONF_TRAN_MODE_OFFSET (29)
#define TRAN_CONF_TRAN_MODE_MSK (0x7)
#define TRAN_CONF_ADDR_WIDTH_OFFSET (26)
#define TRAN_CONF_ADDR_WIDTH_MSK (0x7 << ADDR_WIDTH_OFFSET)
#define TRAN_CONF_POLLEN (1 << 25)
#define TRAN_CONF_CMDEN (1 << 24)
#define TRAN_CONF_FMAT (1 << 23)
#define TRAN_CONF_DMYBITS_OFFSET (17)
#define TRAN_CONF_DMYBITS_MSK (0x3f << DMYBITS_OFFSET)
#define TRAN_CONF_DATEEN (1 << 16)
#define TRAN_CONF_CMD_OFFSET (0)
#define TRAN_CONF_CMD_MSK (0xffff << CMD_OFFSET)
#define TRAN_CONF_CMD_LEN (1 << 15)
/* For SFC_TRIG */
#define TRIG_FLUSH (1 << 2)
#define TRIG_STOP (1 << 1)
#define TRIG_START (1 << 0)
/* For SFC_SCR */
#define CLR_END (1 << 4)
#define CLR_TREQ (1 << 3)
#define CLR_RREQ (1 << 2)
#define CLR_OVER (1 << 1)
#define CLR_UNDER (1 << 0)
/* For SFC_TRAN_CONFx */
#define TRAN_MODE_OFFSET (29)
#define TRAN_MODE_MSK (0x7 << TRAN_MODE_OFFSET)
#define TRAN_SPI_STANDARD (0x0)
#define TRAN_SPI_DUAL (0x1 )
#define TRAN_SPI_QUAD (0x5 )
#define TRAN_SPI_IO_QUAD (0x6 )
#define ADDR_WIDTH_OFFSET (26)
#define ADDR_WIDTH_MSK (0x7 << ADDR_WIDTH_OFFSET)
#define POLLEN (1 << 25)
#define CMDEN (1 << 24)
#define FMAT (1 << 23)
#define DMYBITS_OFFSET (17)
#define DMYBITS_MSK (0x3f << DMYBITS_OFFSET)
#define DATEEN (1 << 16)
#define CMD_OFFSET (0)
#define CMD_MSK (0xffff << CMD_OFFSET)
#define N_MAX 6
#define MAX_SEGS 128
#define CHANNEL_0 0
#define CHANNEL_1 1
#define CHANNEL_2 2
#define CHANNEL_3 3
#define CHANNEL_4 4
#define CHANNEL_5 5
#define ENABLE 1
#define DISABLE 0
#define COM_CMD 1 // common cmd
#define POLL_CMD 2 // the cmd will poll the status of flash,ext: read status
#define DMA_OPS 1
#define CPU_OPS 0
#define TM_STD_SPI 0
#define TM_DI_DO_SPI 1
#define TM_DIO_SPI 2
#define TM_FULL_DIO_SPI 3
#define TM_QI_QO_SPI 5
#define TM_QIO_SPI 6
#define TM_FULL_QIO_SPI 7
#define DEFAULT_ADDRSIZE 3
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
/*SPI NOR FLASH Instructions*/
#define CMD_WREN 0x06 /* Write Enable */
#define CMD_WRDI 0x04 /* Write Disable */
#define CMD_RDSR 0x05 /* Read Status Register */
#define CMD_RDSR_1 0x35 /* Read Status1 Register */
#define CMD_RDSR_2 0x15 /* Read Status2 Register */
#define CMD_WRSR 0x01 /* Write Status Register */
#define CMD_WRSR_1 0x31 /* Write Status1 Register */
#define CMD_WRSR_2 0x11 /* Write Status2 Register */
#define CMD_READ 0x03 /* Read Data */
#define CMD_DUAL_READ 0x3b /* DUAL Read Data */
#define CMD_QUAD_READ 0x6b /* QUAD Read Data */
#define CMD_QUAD_IO_FAST_READ 0xeb /* QUAD FAST Read Data */
#define CMD_QUAD_IO_WORD_FAST_READ 0xe7 /* QUAD IO WORD Read Data */
#define CMD_FAST_READ 0x0B /* Read Data at high speed */
#define CMD_PP 0x02 /* Page Program(write data) */
#define CMD_QPP 0x32 /* QUAD Page Program(write data) */
#define CMD_BE_4K 0x20
#define CMD_BE_32K 0x52 /* Block Erase */
#define CMD_BE_64K 0XD8 /* Block Erase */
#define CMD_CE 0xC7 /* Bulk or Chip Erase */
#define CMD_DP 0xB9 /* Deep Power-Down */
#define CMD_RES 0xAB /* Release from Power-Down and Read Electronic Signature */
#define CMD_REMS 0x90 /* Read Manufacture ID/ Device ID */
#define CMD_RDID 0x9F /* Read Identification */
#define CMD_NON 0x00 /* Read Identification */
#define CMD_RUID 0x4B /* ReadUnique ID */
#define CMD_NON 0x00 /* Read Identification */
#define CMD_EN4B 0xB7 /* Enter 4 bytes address mode */
#define CMD_EX4B 0xE9 /* Exit 4 bytes address mode */
struct cmd_info
{
uint32_t cmd;
uint32_t cmd_len;/*reserved; not use*/
uint32_t dataen;
uint32_t sta_exp;
uint32_t sta_msk;
};
struct sfc_transfer
{
uint32_t direction;
struct cmd_info *cmd_info;
uint32_t addr_len;
uint32_t addr;
uint32_t addr_plus;
uint32_t addr_dummy_bits;/*cmd + addr_dummy_bits + addr*/
const uint8_t *data;
uint32_t data_dummy_bits;/*addr + data_dummy_bits + data*/
uint32_t len;
uint32_t cur_len;
uint32_t sfc_mode;
uint32_t ops_mode;
uint32_t phase_format;/*we just use default value;phase1:cmd+dummy+addr... phase0:cmd+addr+dummy...*/
rt_list_t transfer_list;
};
struct sfc_message
{
rt_list_t transfers;
uint32_t actual_length;
uint32_t status;
};
struct sfc
{
void *iomem;
int irq;
struct clk *clk;
struct clk *clk_gate;
uint32_t src_clk;
uint32_t threshold;
struct sfc_transfer *transfer;
struct rt_completion done;
};
struct sfc_quad_mode
{
uint8_t RDSR_CMD;
uint32_t RD_DATE_SIZE;//the data is write the spi status register for QE bit
uint8_t sfc_mode;
uint8_t WRSR_CMD;
uint32_t WD_DATE_SIZE;//the data is write the spi status register for QE bit
uint8_t cmd_read;
uint32_t RDSR_DATE;//the data is write the spi status register for QE bit
uint32_t WRSR_DATE;//this bit should be the flash QUAD mode enable
uint32_t dummy_byte;
};
struct sfc_flash
{
struct rt_mtd_nor_device mtd;
char *name;
uint32_t id;
uint8_t uid[8];
uint32_t pagesize;
uint32_t sectorsize;
uint32_t chipsize;
uint32_t erasesize;
uint32_t writesize;
uint32_t addrsize;
struct sfc *sfc;
uint32_t sfc_mode;
#ifdef SFC_USE_QUAD
struct sfc_quad_mode *quad_mode;
#endif
struct rt_mutex lock;
};
int sfc_norflash_probe(struct sfc_flash *flash);
size_t sfc_norflash_read(struct sfc_flash *flash, rt_off_t from, uint8_t *buf, size_t len);
size_t sfc_norflash_write(struct sfc_flash *flash, rt_off_t to, const uint8_t *buf, size_t len);
int sfc_norflash_erase_sector(struct sfc_flash *flash, uint32_t addr);
int sfc_norflash_set_addr_width_4byte(struct sfc_flash *flash,int on);
#endif /* DRIVER_DRV_SFC_H_ */
|