blob: cf40e2ea944c5ed9ecce97d6cf39618550e0cae7 [file] [log] [blame]
Norman James6a58a272015-10-07 14:34:16 -05001#ifndef __LIBFLASH_PRIV_H
2#define __LIBFLASH_PRIV_H
3
4#include <ccan/endian/endian.h>
5#include <ccan/array_size/array_size.h>
6#include <ccan/container_of/container_of.h>
7
8/* Flash commands */
9#define CMD_WRSR 0x01 /* Write Status Register (also config. on Macronix) */
10#define CMD_PP 0x02 /* Page Program */
11#define CMD_READ 0x03 /* READ */
12#define CMD_WRDI 0x04 /* Write Disable */
13#define CMD_RDSR 0x05 /* Read Status Register */
14#define CMD_WREN 0x06 /* Write Enable */
15#define CMD_RDCR 0x15 /* Read configuration register (Macronix) */
16#define CMD_SE 0x20 /* Sector (4K) Erase */
17#define CMD_RDSCUR 0x2b /* Read Security Register (Macronix) */
18#define CMD_BE32K 0x52 /* Block (32K) Erase */
19#define CMD_RDSFDP 0x5a /* Read SFDP JEDEC info */
20#define CMD_CE 0x60 /* Chip Erase (Macronix/Winbond) */
21#define CMD_MIC_WREVCONF 0x61 /* Micron Write Enhanced Volatile Config */
22#define CMD_MIC_RDEVCONF 0x65 /* Micron Read Enhanced Volatile Config */
23#define CMD_MIC_RDFLST 0x70 /* Micron Read Flag Status */
24#define CMD_MIC_WRVCONF 0x81 /* Micron Write Volatile Config */
25#define CMD_MIC_RDVCONF 0x85 /* Micron Read Volatile Config */
26#define CMD_RDID 0x9f /* Read JEDEC ID */
27#define CMD_EN4B 0xb7 /* Enable 4B addresses */
28#define CMD_MIC_BULK_ERASE 0xc7 /* Micron Bulk Erase */
29#define CMD_BE 0xd8 /* Block (64K) Erase */
30#define CMD_RDDPB 0xe0 /* Read dynamic protection (Macronix) */
31#define CMD_RDSPB 0xe2 /* Read static protection (Macronix) */
32#define CMD_EX4B 0xe9 /* Exit 4B addresses */
33
34/* Flash status bits */
35#define STAT_WIP 0x01
36#define STAT_WEN 0x02
37
38/* This isn't exposed to clients but is to controllers */
39struct flash_info {
40 uint32_t id;
41 uint32_t size;
42 uint32_t flags;
43#define FL_ERASE_4K 0x00000001 /* Supports 4k erase */
44#define FL_ERASE_32K 0x00000002 /* Supports 32k erase */
45#define FL_ERASE_64K 0x00000004 /* Supports 64k erase */
46#define FL_ERASE_CHIP 0x00000008 /* Supports 0x60 cmd chip erase */
47#define FL_ERASE_BULK 0x00000010 /* Supports 0xc7 cmd bulk erase */
48#define FL_MICRON_BUGS 0x00000020 /* Various micron bug workarounds */
49#define FL_ERASE_ALL (FL_ERASE_4K | FL_ERASE_32K | FL_ERASE_64K | \
50 FL_ERASE_CHIP)
51#define FL_CAN_4B 0x00000010 /* Supports 4b mode */
52 const char *name;
53};
54
55/* Flash controller, return negative values for errors */
56struct spi_flash_ctrl {
57 /*
58 * The controller can provide basically two interfaces,
59 * either a fairly high level one and a lower level one.
60 *
61 * If all functions of the high level interface are
62 * implemented then the low level one is optional. A
63 * controller can implement some of the high level one
64 * in which case the missing ones will be handled by
65 * libflash using the low level interface.
66 *
67 * There are also some common functions.
68 */
69
70 /* **************************************************
71 * Misc / common functions
72 * **************************************************/
73
74 /*
75 * - setup(ctrl, tsize)
76 *
77 * Provides the controller with an option to configure itself
78 * based on the specific flash type. It can also override some
79 * settings in the info block such as available erase sizes etc...
80 * which can be needed for high level controllers. It can also
81 * override the total flash size.
82 */
83 int (*setup)(struct spi_flash_ctrl *ctrl, uint32_t *tsize);
84
85 /*
86 * - set_4b(ctrl, enable)
87 *
88 * enable : Switch to 4bytes (true) or 3bytes (false) address mode
89 *
90 * Set the controller's address size. If the controller doesn't
91 * implement the low level command interface, then this must also
92 * configure the flash chip itself. Otherwise, libflash will do it.
93 *
94 * Note that if this isn't implemented, then libflash might still
95 * try to switch large flash chips to 4b mode if the low level cmd
96 * interface is implemented. It will then also stop using the high
97 * level command interface since it's assumed that it cannot handle
98 * 4b addresses.
99 */
100 int (*set_4b)(struct spi_flash_ctrl *ctrl, bool enable);
101
102
103
104 /* **************************************************
105 * High level interface
106 * **************************************************/
107
108 /*
109 * Read chip ID. This can return up to 16 bytes though the
110 * current libflash will only use 3 (room for things like
111 * extended micron stuff).
112 *
113 * id_size is set on entry to the buffer size and need to
114 * be adjusted to the actual ID size read.
115 *
116 * If NULL, libflash will use cmd_rd to send normal RDID (0x9f)
117 * command.
118 */
119 int (*chip_id)(struct spi_flash_ctrl *ctrl, uint8_t *id_buf,
120 uint32_t *id_size);
121
122 /*
123 * Read from flash. There is no specific constraint on
124 * alignment or size other than not reading outside of
125 * the chip.
126 *
127 * If NULL, libflash will use cmd_rd to send normal
128 * READ (0x03) commands.
129 */
130 int (*read)(struct spi_flash_ctrl *ctrl, uint32_t addr, void *buf,
131 uint32_t size);
132
133 /*
134 * Write to flash. There is no specific constraint on
135 * alignment or size other than not reading outside of
136 * the chip. The driver is responsible for handling
137 * 256-bytes page alignment and to send the write enable
138 * commands when needed.
139 *
140 * If absent, libflash will use cmd_wr to send WREN (0x06)
141 * and PP (0x02) commands.
142 *
143 * Note: This does not need to handle erasing. libflash
144 * will ensure that this is never used for changing a bit
145 * value from 0 to 1.
146 */
147 int (*write)(struct spi_flash_ctrl *ctrl, uint32_t addr,
148 const void *buf, uint32_t size);
149
150 /*
151 * Erase. This will be called for erasing a portion of
152 * the flash using a granularity (alignment of start and
153 * size) that is no less than the smallest supported
154 * erase size in the info block (*). The driver is
155 * responsible to send write enable commands when needed.
156 *
157 * If absent, libflash will use cmd_wr to send WREN (0x06)
158 * and either of SE (0x20), BE32K (0x52) or BE (0xd8)
159 * based on what the flash chip supports.
160 *
161 * (*) Note: This is called with addr=0 and size=0xffffffff
162 * in which case this is used as a "chip erase". Return
163 * FLASH_ERR_CHIP_ER_NOT_SUPPORTED if not supported. Some
164 * future version of libflash might then emulate it using
165 * normal erase commands.
166 */
167 int (*erase)(struct spi_flash_ctrl *ctrl, uint32_t addr,
168 uint32_t size);
169
170 /* **************************************************
171 * Low level interface
172 * **************************************************/
173
174 /* Note: For commands with no data, libflash will might use
175 * either cmd_rd or cmd_wr.
176 */
177
178 /*
179 * - cmd_rd(ctrl, cmd, has_addr, address, buffer, size);
180 *
181 * cmd : command opcode
182 * has_addr : send an address after the command
183 * address : address to send
184 * buffer : buffer for additional data to read (or NULL)
185 * size : size of additional data read (or NULL)
186 *
187 * Sends a command and optionally read additional data
188 */
189 int (*cmd_rd)(struct spi_flash_ctrl *ctrl, uint8_t cmd,
190 bool has_addr, uint32_t addr, void *buffer,
191 uint32_t size);
192 /*
193 * - cmd_wr(ctrl, cmd, has_addr, address, buffer, size);
194 *
195 * cmd : command opcode
196 * has_addr : send an address after the command
197 * address : address to send
198 * buffer : buffer for additional data to write (or NULL)
199 * size : size of additional data write (or NULL)
200 *
201 * Sends a command and optionally write additional data
202 */
203 int (*cmd_wr)(struct spi_flash_ctrl *ctrl, uint8_t cmd,
204 bool has_addr, uint32_t addr, const void *buffer,
205 uint32_t size);
206
207 /* The core will establish this at init, after chip ID has
208 * been probed
209 */
210 struct flash_info *finfo;
211};
212
213extern int fl_wren(struct spi_flash_ctrl *ct);
214extern int fl_read_stat(struct spi_flash_ctrl *ct, uint8_t *stat);
215extern int fl_sync_wait_idle(struct spi_flash_ctrl *ct);
216
217#endif /* LIBFLASH_PRIV_H */