2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * Copyright 2008, Network Appliance Inc.
6 * Jason McMullan <mcmullan@netapp.com>
8 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
9 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
11 * See file CREDITS for list of people who contributed to this
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 #include <spi_flash.h>
34 #include "spi_flash_internal.h"
36 /* M25Pxx-specific commands */
37 #define CMD_M25PXX_WREN 0x06 /* Write Enable */
38 #define CMD_M25PXX_WRDI 0x04 /* Write Disable */
39 #define CMD_M25PXX_RDSR 0x05 /* Read Status Register */
40 #define CMD_M25PXX_WRSR 0x01 /* Write Status Register */
41 #define CMD_M25PXX_READ 0x03 /* Read Data Bytes */
42 #define CMD_M25PXX_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
43 #define CMD_M25PXX_PP 0x02 /* Page Program */
44 #define CMD_M25PXX_SE 0xd8 /* Sector Erase */
45 #define CMD_M25PXX_BE 0xc7 /* Bulk Erase */
46 #define CMD_M25PXX_DP 0xb9 /* Deep Power-down */
47 #define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */
49 #define STM_ID_M25P16 0x15
50 #define STM_ID_M25P20 0x12
51 #define STM_ID_M25P32 0x16
52 #define STM_ID_M25P40 0x13
53 #define STM_ID_M25P64 0x17
54 #define STM_ID_M25P80 0x14
55 #define STM_ID_M25P128 0x18
57 #define STMICRO_SR_WIP (1 << 0) /* Write-in-Progress */
59 struct stmicro_spi_flash_params
{
67 /* spi_flash needs to be first so upper layers can free() it */
68 struct stmicro_spi_flash
{
69 struct spi_flash flash
;
70 const struct stmicro_spi_flash_params
*params
;
73 static inline struct stmicro_spi_flash
*to_stmicro_spi_flash(struct spi_flash
76 return container_of(flash
, struct stmicro_spi_flash
, flash
);
79 static const struct stmicro_spi_flash_params stmicro_spi_flash_table
[] = {
81 .idcode1
= STM_ID_M25P16
,
83 .pages_per_sector
= 256,
88 .idcode1
= STM_ID_M25P20
,
90 .pages_per_sector
= 256,
95 .idcode1
= STM_ID_M25P32
,
97 .pages_per_sector
= 256,
102 .idcode1
= STM_ID_M25P40
,
104 .pages_per_sector
= 256,
109 .idcode1
= STM_ID_M25P64
,
111 .pages_per_sector
= 256,
116 .idcode1
= STM_ID_M25P80
,
118 .pages_per_sector
= 256,
123 .idcode1
= STM_ID_M25P128
,
125 .pages_per_sector
= 1024,
131 static int stmicro_wait_ready(struct spi_flash
*flash
, unsigned long timeout
)
133 struct spi_slave
*spi
= flash
->spi
;
134 unsigned long timebase
;
136 u8 cmd
= CMD_M25PXX_RDSR
;
139 ret
= spi_xfer(spi
, 8, &cmd
, NULL
, SPI_XFER_BEGIN
);
141 debug("SF: Failed to send command %02x: %d\n", cmd
, ret
);
145 timebase
= get_timer(0);
147 ret
= spi_xfer(spi
, 8, NULL
, &status
, 0);
151 if ((status
& STMICRO_SR_WIP
) == 0)
154 } while (get_timer(timebase
) < timeout
);
156 spi_xfer(spi
, 0, NULL
, NULL
, SPI_XFER_END
);
158 if ((status
& STMICRO_SR_WIP
) == 0)
165 static int stmicro_read_fast(struct spi_flash
*flash
,
166 u32 offset
, size_t len
, void *buf
)
168 struct stmicro_spi_flash
*stm
= to_stmicro_spi_flash(flash
);
169 unsigned long page_addr
;
170 unsigned long page_size
;
173 page_size
= stm
->params
->page_size
;
174 page_addr
= offset
/ page_size
;
176 cmd
[0] = CMD_READ_ARRAY_FAST
;
177 cmd
[1] = page_addr
>> 8;
179 cmd
[3] = offset
% page_size
;
182 return spi_flash_read_common(flash
, cmd
, sizeof(cmd
), buf
, len
);
185 static int stmicro_write(struct spi_flash
*flash
,
186 u32 offset
, size_t len
, const void *buf
)
188 struct stmicro_spi_flash
*stm
= to_stmicro_spi_flash(flash
);
189 unsigned long page_addr
;
190 unsigned long byte_addr
;
191 unsigned long page_size
;
197 page_size
= stm
->params
->page_size
;
198 page_addr
= offset
/ page_size
;
199 byte_addr
= offset
% page_size
;
201 ret
= spi_claim_bus(flash
->spi
);
203 debug("SF: Unable to claim SPI bus\n");
208 for (actual
= 0; actual
< len
; actual
+= chunk_len
) {
209 chunk_len
= min(len
- actual
, page_size
- byte_addr
);
211 cmd
[0] = CMD_M25PXX_PP
;
212 cmd
[1] = page_addr
>> 8;
217 ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
218 buf
+ actual
, cmd
[0], cmd
[1], cmd
[2], cmd
[3], chunk_len
);
220 ret
= spi_flash_cmd(flash
->spi
, CMD_M25PXX_WREN
, NULL
, 0);
222 debug("SF: Enabling Write failed\n");
226 ret
= spi_flash_cmd_write(flash
->spi
, cmd
, 4,
227 buf
+ actual
, chunk_len
);
229 debug("SF: STMicro Page Program failed\n");
233 ret
= stmicro_wait_ready(flash
, SPI_FLASH_PROG_TIMEOUT
);
235 debug("SF: STMicro page programming timed out\n");
243 debug("SF: STMicro: Successfully programmed %u bytes @ 0x%x\n",
246 spi_release_bus(flash
->spi
);
250 int stmicro_erase(struct spi_flash
*flash
, u32 offset
, size_t len
)
252 struct stmicro_spi_flash
*stm
= to_stmicro_spi_flash(flash
);
253 unsigned long sector_size
;
259 * This function currently uses sector erase only.
260 * probably speed things up by using bulk erase
264 sector_size
= stm
->params
->page_size
* stm
->params
->pages_per_sector
;
266 if (offset
% sector_size
|| len
% sector_size
) {
267 debug("SF: Erase offset/length not multiple of sector size\n");
272 cmd
[0] = CMD_M25PXX_SE
;
276 ret
= spi_claim_bus(flash
->spi
);
278 debug("SF: Unable to claim SPI bus\n");
283 for (actual
= 0; actual
< len
; actual
++) {
284 cmd
[1] = offset
>> 16;
285 offset
+= sector_size
;
287 ret
= spi_flash_cmd(flash
->spi
, CMD_M25PXX_WREN
, NULL
, 0);
289 debug("SF: Enabling Write failed\n");
293 ret
= spi_flash_cmd_write(flash
->spi
, cmd
, 4, NULL
, 0);
295 debug("SF: STMicro page erase failed\n");
299 ret
= stmicro_wait_ready(flash
, SPI_FLASH_PAGE_ERASE_TIMEOUT
);
301 debug("SF: STMicro page erase timed out\n");
306 debug("SF: STMicro: Successfully erased %u bytes @ 0x%x\n",
307 len
* sector_size
, offset
);
309 spi_release_bus(flash
->spi
);
313 struct spi_flash
*spi_flash_probe_stmicro(struct spi_slave
*spi
, u8
* idcode
)
315 const struct stmicro_spi_flash_params
*params
;
316 struct stmicro_spi_flash
*stm
;
319 for (i
= 0; i
< ARRAY_SIZE(stmicro_spi_flash_table
); i
++) {
320 params
= &stmicro_spi_flash_table
[i
];
321 if (params
->idcode1
== idcode
[2]) {
326 if (i
== ARRAY_SIZE(stmicro_spi_flash_table
)) {
327 debug("SF: Unsupported STMicro ID %02x\n", idcode
[1]);
331 stm
= malloc(sizeof(struct stmicro_spi_flash
));
333 debug("SF: Failed to allocate memory\n");
337 stm
->params
= params
;
338 stm
->flash
.spi
= spi
;
339 stm
->flash
.name
= params
->name
;
341 stm
->flash
.write
= stmicro_write
;
342 stm
->flash
.erase
= stmicro_erase
;
343 stm
->flash
.read
= stmicro_read_fast
;
344 stm
->flash
.size
= params
->page_size
* params
->pages_per_sector
345 * params
->nr_sectors
;
347 debug("SF: Detected %s with page size %u, total %u bytes\n",
348 params
->name
, params
->page_size
, stm
->flash
.size
);