blob: 0bc7ee72b3f3ba2c38ab89c30868ff277ecaff18 [file] [log] [blame]
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +00001/*
2 * This file is part of the flashrom project.
3 *
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +00004 * Copyright (C) 2007, 2008 Carl-Daniel Hailfinger
Stefan Reinauera9424d52008-06-27 16:28:34 +00005 * Copyright (C) 2008 coresystems GmbH
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * Contains the generic SPI framework
23 */
24
25#include <stdio.h>
26#include <pci/pci.h>
27#include <stdint.h>
28#include <string.h>
29#include "flash.h"
Carl-Daniel Hailfingerd6cbf762008-05-13 14:58:23 +000030#include "spi.h"
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000031
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +000032void spi_prettyprint_status_register(struct flashchip *flash);
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000033
Uwe Hermann394131e2008-10-18 21:14:13 +000034int spi_command(unsigned int writecnt, unsigned int readcnt,
35 const unsigned char *writearr, unsigned char *readarr)
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000036{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000037 switch (flashbus) {
38 case BUS_TYPE_IT87XX_SPI:
Uwe Hermann394131e2008-10-18 21:14:13 +000039 return it8716f_spi_command(writecnt, readcnt, writearr,
40 readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000041 case BUS_TYPE_ICH7_SPI:
42 case BUS_TYPE_ICH9_SPI:
43 case BUS_TYPE_VIA_SPI:
Uwe Hermann394131e2008-10-18 21:14:13 +000044 return ich_spi_command(writecnt, readcnt, writearr, readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +000045 case BUS_TYPE_SB600_SPI:
46 return sb600_spi_command(writecnt, readcnt, writearr, readarr);
Peter Stugebf196e92009-01-26 03:08:45 +000047 case BUS_TYPE_WBSIO_SPI:
48 return wbsio_spi_command(writecnt, readcnt, writearr, readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000049 default:
Uwe Hermann394131e2008-10-18 21:14:13 +000050 printf_debug
51 ("%s called, but no SPI chipset/strapping detected\n",
52 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000053 }
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000054 return 1;
55}
56
Rudolf Marek48a85e42008-06-30 21:45:17 +000057static int spi_rdid(unsigned char *readarr, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000058{
Uwe Hermann394131e2008-10-18 21:14:13 +000059 const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000060
Peter Stugef83221b2008-07-07 06:38:51 +000061 if (spi_command(sizeof(cmd), bytes, cmd, readarr))
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000062 return 1;
Uwe Hermann394131e2008-10-18 21:14:13 +000063 printf_debug("RDID returned %02x %02x %02x.\n", readarr[0], readarr[1],
64 readarr[2]);
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000065 return 0;
66}
67
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000068static int spi_rems(unsigned char *readarr)
69{
70 const unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
71
72 if (spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr))
73 return 1;
74 printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
75 return 0;
76}
77
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000078static int spi_res(unsigned char *readarr)
79{
Uwe Hermann394131e2008-10-18 21:14:13 +000080 const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000081
Peter Stugef83221b2008-07-07 06:38:51 +000082 if (spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr))
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000083 return 1;
84 printf_debug("RES returned %02x.\n", readarr[0]);
85 return 0;
86}
87
Uwe Hermann7b2969b2009-04-15 10:52:49 +000088int spi_write_enable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000089{
Uwe Hermann394131e2008-10-18 21:14:13 +000090 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +000091 int result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000092
93 /* Send WREN (Write Enable) */
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +000094 result = spi_command(sizeof(cmd), 0, cmd, NULL);
95 if (result) {
96 printf_debug("spi_write_enable failed");
97 switch (flashbus) {
98 case BUS_TYPE_ICH7_SPI:
99 case BUS_TYPE_ICH9_SPI:
100 case BUS_TYPE_VIA_SPI:
101 printf_debug(" due to SPI master limitation, ignoring"
102 " and hoping it will be run as PREOP\n");
103 return 0;
104 default:
105 printf_debug("\n");
106 }
107 }
108 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000109}
110
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000111int spi_write_disable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000112{
Uwe Hermann394131e2008-10-18 21:14:13 +0000113 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000114
115 /* Send WRDI (Write Disable) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000116 return spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000117}
118
Rudolf Marek48a85e42008-06-30 21:45:17 +0000119static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000120{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000121 unsigned char readarr[4];
Carl-Daniel Hailfinger1263d2a2008-02-06 22:07:58 +0000122 uint32_t manuf_id;
123 uint32_t model_id;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000124
Rudolf Marek48a85e42008-06-30 21:45:17 +0000125 if (spi_rdid(readarr, bytes))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000126 return 0;
127
128 if (!oddparity(readarr[0]))
129 printf_debug("RDID byte 0 parity violation.\n");
130
131 /* Check if this is a continuation vendor ID */
132 if (readarr[0] == 0x7f) {
133 if (!oddparity(readarr[1]))
134 printf_debug("RDID byte 1 parity violation.\n");
135 manuf_id = (readarr[0] << 8) | readarr[1];
136 model_id = readarr[2];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000137 if (bytes > 3) {
138 model_id <<= 8;
139 model_id |= readarr[3];
140 }
Peter Stugeda4e5f32008-06-24 01:22:03 +0000141 } else {
142 manuf_id = readarr[0];
143 model_id = (readarr[1] << 8) | readarr[2];
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000144 }
145
Peter Stuge5cafc332009-01-25 23:52:45 +0000146 printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, manuf_id,
Uwe Hermann394131e2008-10-18 21:14:13 +0000147 model_id);
Peter Stugeda4e5f32008-06-24 01:22:03 +0000148
Uwe Hermann394131e2008-10-18 21:14:13 +0000149 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
Peter Stugeda4e5f32008-06-24 01:22:03 +0000150 /* Print the status register to tell the
151 * user about possible write protection.
152 */
153 spi_prettyprint_status_register(flash);
154
155 return 1;
156 }
157
158 /* Test if this is a pure vendor match. */
159 if (manuf_id == flash->manufacture_id &&
160 GENERIC_DEVICE_ID == flash->model_id)
161 return 1;
162
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000163 return 0;
164}
165
Uwe Hermann394131e2008-10-18 21:14:13 +0000166int probe_spi_rdid(struct flashchip *flash)
167{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000168 return probe_spi_rdid_generic(flash, 3);
169}
170
171/* support 4 bytes flash ID */
Uwe Hermann394131e2008-10-18 21:14:13 +0000172int probe_spi_rdid4(struct flashchip *flash)
173{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000174 /* only some SPI chipsets support 4 bytes commands */
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000175 switch (flashbus) {
176 case BUS_TYPE_ICH7_SPI:
177 case BUS_TYPE_ICH9_SPI:
178 case BUS_TYPE_VIA_SPI:
Jason Wanga3f04be2008-11-28 21:36:51 +0000179 case BUS_TYPE_SB600_SPI:
Peter Stugebf196e92009-01-26 03:08:45 +0000180 case BUS_TYPE_WBSIO_SPI:
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000181 return probe_spi_rdid_generic(flash, 4);
182 default:
183 printf_debug("4b ID not supported on this SPI controller\n");
184 }
185
186 return 0;
Rudolf Marek48a85e42008-06-30 21:45:17 +0000187}
188
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000189int probe_spi_rems(struct flashchip *flash)
190{
191 unsigned char readarr[JEDEC_REMS_INSIZE];
192 uint32_t manuf_id, model_id;
193
194 if (spi_rems(readarr))
195 return 0;
196
197 manuf_id = readarr[0];
198 model_id = readarr[1];
199
200 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id,
201 model_id);
202
203 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
204 /* Print the status register to tell the
205 * user about possible write protection.
206 */
207 spi_prettyprint_status_register(flash);
208
209 return 1;
210 }
211
212 /* Test if this is a pure vendor match. */
213 if (manuf_id == flash->manufacture_id &&
214 GENERIC_DEVICE_ID == flash->model_id)
215 return 1;
216
217 return 0;
218}
219
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000220int probe_spi_res(struct flashchip *flash)
221{
222 unsigned char readarr[3];
223 uint32_t model_id;
Peter Stugeda4e5f32008-06-24 01:22:03 +0000224
Carl-Daniel Hailfinger92a54ca2008-11-27 22:48:48 +0000225 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
226 * In that case, RES is pointless.
227 */
228 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
229 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000230 return 0;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000231
Peter Stugeda4e5f32008-06-24 01:22:03 +0000232 if (spi_res(readarr))
233 return 0;
234
235 model_id = readarr[0];
236 printf_debug("%s: id 0x%x\n", __FUNCTION__, model_id);
237 if (model_id != flash->model_id)
238 return 0;
239
240 /* Print the status register to tell the
241 * user about possible write protection.
242 */
243 spi_prettyprint_status_register(flash);
244 return 1;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000245}
246
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000247uint8_t spi_read_status_register(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000248{
Uwe Hermann394131e2008-10-18 21:14:13 +0000249 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
Peter Stugebf196e92009-01-26 03:08:45 +0000250 unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000251
252 /* Read Status Register */
Jason Wanga3f04be2008-11-28 21:36:51 +0000253 if (flashbus == BUS_TYPE_SB600_SPI) {
254 /* SB600 uses a different way to read status register. */
255 return sb600_read_status_register();
256 } else {
257 spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
258 }
259
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000260 return readarr[0];
261}
262
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000263/* Prettyprint the status register. Common definitions. */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000264void spi_prettyprint_status_register_common(uint8_t status)
265{
266 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000267 "%sset\n", (status & (1 << 5)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000268 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000269 "%sset\n", (status & (1 << 4)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000270 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000271 "%sset\n", (status & (1 << 3)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000272 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000273 "%sset\n", (status & (1 << 2)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000274 printf_debug("Chip status register: Write Enable Latch (WEL) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000275 "%sset\n", (status & (1 << 1)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000276 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000277 "%sset\n", (status & (1 << 0)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000278}
279
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000280/* Prettyprint the status register. Works for
281 * ST M25P series
282 * MX MX25L series
283 */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000284void spi_prettyprint_status_register_st_m25p(uint8_t status)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000285{
286 printf_debug("Chip status register: Status Register Write Disable "
Uwe Hermann394131e2008-10-18 21:14:13 +0000287 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000288 printf_debug("Chip status register: Bit 6 is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000289 "%sset\n", (status & (1 << 6)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000290 spi_prettyprint_status_register_common(status);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000291}
292
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000293void spi_prettyprint_status_register_sst25(uint8_t status)
294{
295 printf_debug("Chip status register: Block Protect Write Disable "
296 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
297 printf_debug("Chip status register: Auto Address Increment Programming "
298 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
299 spi_prettyprint_status_register_common(status);
300}
301
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000302/* Prettyprint the status register. Works for
303 * SST 25VF016
304 */
305void spi_prettyprint_status_register_sst25vf016(uint8_t status)
306{
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000307 const char *bpt[] = {
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000308 "none",
309 "1F0000H-1FFFFFH",
310 "1E0000H-1FFFFFH",
311 "1C0000H-1FFFFFH",
312 "180000H-1FFFFFH",
313 "100000H-1FFFFFH",
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000314 "all", "all"
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000315 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000316 spi_prettyprint_status_register_sst25(status);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000317 printf_debug("Resulting block protection : %s\n",
Uwe Hermann394131e2008-10-18 21:14:13 +0000318 bpt[(status & 0x1c) >> 2]);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000319}
320
Peter Stuge5fecee42009-01-26 03:23:50 +0000321void spi_prettyprint_status_register_sst25vf040b(uint8_t status)
322{
323 const char *bpt[] = {
324 "none",
325 "0x70000-0x7ffff",
326 "0x60000-0x7ffff",
327 "0x40000-0x7ffff",
328 "all blocks", "all blocks", "all blocks", "all blocks"
329 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000330 spi_prettyprint_status_register_sst25(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000331 printf_debug("Resulting block protection : %s\n",
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000332 bpt[(status & 0x1c) >> 2]);
Peter Stuge5fecee42009-01-26 03:23:50 +0000333}
334
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000335void spi_prettyprint_status_register(struct flashchip *flash)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000336{
337 uint8_t status;
338
Peter Stugefa8c5502008-05-10 23:07:52 +0000339 status = spi_read_status_register();
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000340 printf_debug("Chip status register is %02x\n", status);
341 switch (flash->manufacture_id) {
342 case ST_ID:
Carl-Daniel Hailfingerf43e6422008-05-15 22:32:08 +0000343 if (((flash->model_id & 0xff00) == 0x2000) ||
344 ((flash->model_id & 0xff00) == 0x2500))
345 spi_prettyprint_status_register_st_m25p(status);
346 break;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000347 case MX_ID:
348 if ((flash->model_id & 0xff00) == 0x2000)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000349 spi_prettyprint_status_register_st_m25p(status);
350 break;
351 case SST_ID:
Peter Stuge5fecee42009-01-26 03:23:50 +0000352 switch (flash->model_id) {
353 case 0x2541:
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000354 spi_prettyprint_status_register_sst25vf016(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000355 break;
356 case 0x8d:
357 case 0x258d:
358 spi_prettyprint_status_register_sst25vf040b(status);
359 break;
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000360 case 0x258e:
361 spi_prettyprint_status_register_sst25(status);
362 break;
Peter Stuge5fecee42009-01-26 03:23:50 +0000363 }
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000364 break;
365 }
366}
Uwe Hermann394131e2008-10-18 21:14:13 +0000367
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000368int spi_chip_erase_60(struct flashchip *flash)
369{
370 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000371 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000372
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000373 result = spi_disable_blockprotect();
374 if (result) {
375 printf_debug("spi_disable_blockprotect failed\n");
376 return result;
377 }
378 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000379 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000380 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000381 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000382 result = spi_command(sizeof(cmd), 0, cmd, NULL);
383 if (result) {
384 printf_debug("spi_chip_erase_60 failed sending erase\n");
385 return result;
386 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000387 /* Wait until the Write-In-Progress bit is cleared.
388 * This usually takes 1-85 s, so wait in 1 s steps.
389 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000390 /* FIXME: We assume spi_read_status_register will never fail. */
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000391 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
392 sleep(1);
393 return 0;
394}
395
Peter Stugefa8c5502008-05-10 23:07:52 +0000396int spi_chip_erase_c7(struct flashchip *flash)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000397{
Uwe Hermann394131e2008-10-18 21:14:13 +0000398 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000399 int result;
Uwe Hermann394131e2008-10-18 21:14:13 +0000400
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000401 result = spi_disable_blockprotect();
402 if (result) {
403 printf_debug("spi_disable_blockprotect failed\n");
404 return result;
405 }
406 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000407 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000408 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000409 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000410 result = spi_command(sizeof(cmd), 0, cmd, NULL);
411 if (result) {
412 printf_debug("spi_chip_erase_60 failed sending erase\n");
413 return result;
414 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000415 /* Wait until the Write-In-Progress bit is cleared.
416 * This usually takes 1-85 s, so wait in 1 s steps.
417 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000418 /* FIXME: We assume spi_read_status_register will never fail. */
Peter Stugefa8c5502008-05-10 23:07:52 +0000419 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000420 sleep(1);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000421 return 0;
422}
423
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000424int spi_chip_erase_60_c7(struct flashchip *flash)
425{
426 int result;
427 result = spi_chip_erase_60(flash);
428 if (result) {
429 printf_debug("spi_chip_erase_60 failed, trying c7\n");
430 result = spi_chip_erase_c7(flash);
431 }
432 return result;
433}
434
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000435int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
436{
437 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000438 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000439
440 cmd[1] = (addr & 0x00ff0000) >> 16;
441 cmd[2] = (addr & 0x0000ff00) >> 8;
442 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000443 result = spi_write_enable();
444 if (result)
445 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000446 /* Send BE (Block Erase) */
447 spi_command(sizeof(cmd), 0, cmd, NULL);
448 /* Wait until the Write-In-Progress bit is cleared.
449 * This usually takes 100-4000 ms, so wait in 100 ms steps.
450 */
451 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
452 usleep(100 * 1000);
453 return 0;
454}
455
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000456/* Block size is usually
457 * 64k for Macronix
458 * 32k for SST
459 * 4-32k non-uniform for EON
460 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000461int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000462{
Uwe Hermann394131e2008-10-18 21:14:13 +0000463 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000464 int result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000465
466 cmd[1] = (addr & 0x00ff0000) >> 16;
467 cmd[2] = (addr & 0x0000ff00) >> 8;
468 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000469 result = spi_write_enable();
470 if (result)
471 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000472 /* Send BE (Block Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000473 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000474 /* Wait until the Write-In-Progress bit is cleared.
475 * This usually takes 100-4000 ms, so wait in 100 ms steps.
476 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000477 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000478 usleep(100 * 1000);
479 return 0;
480}
481
Stefan Reinauer424ed222008-10-29 22:13:20 +0000482int spi_chip_erase_d8(struct flashchip *flash)
483{
484 int i, rc = 0;
485 int total_size = flash->total_size * 1024;
486 int erase_size = 64 * 1024;
487
488 spi_disable_blockprotect();
489
490 printf("Erasing chip: \n");
491
492 for (i = 0; i < total_size / erase_size; i++) {
493 rc = spi_block_erase_d8(flash, i * erase_size);
494 if (rc) {
495 printf("Error erasing block at 0x%x\n", i);
496 break;
497 }
498 }
499
500 printf("\n");
501
502 return rc;
503}
504
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000505/* Sector size is usually 4k, though Macronix eliteflash has 64k */
Peter Stugefa8c5502008-05-10 23:07:52 +0000506int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000507{
Uwe Hermann394131e2008-10-18 21:14:13 +0000508 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000509 int result;
510
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000511 cmd[1] = (addr & 0x00ff0000) >> 16;
512 cmd[2] = (addr & 0x0000ff00) >> 8;
513 cmd[3] = (addr & 0x000000ff);
514
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000515 result = spi_write_enable();
516 if (result)
517 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000518 /* Send SE (Sector Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000519 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000520 /* Wait until the Write-In-Progress bit is cleared.
521 * This usually takes 15-800 ms, so wait in 10 ms steps.
522 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000523 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000524 usleep(10 * 1000);
525 return 0;
526}
527
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000528int spi_write_status_enable(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000529{
530 const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
531
532 /* Send EWSR (Enable Write Status Register). */
533 return spi_command(JEDEC_EWSR_OUTSIZE, JEDEC_EWSR_INSIZE, cmd, NULL);
534}
535
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000536/*
537 * This is according the SST25VF016 datasheet, who knows it is more
538 * generic that this...
539 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000540int spi_write_status_register(int status)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000541{
Uwe Hermann394131e2008-10-18 21:14:13 +0000542 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
543 { JEDEC_WRSR, (unsigned char)status };
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000544
545 /* Send WRSR (Write Status Register) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000546 return spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000547}
548
549void spi_byte_program(int address, uint8_t byte)
550{
Uwe Hermann394131e2008-10-18 21:14:13 +0000551 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
552 JEDEC_BYTE_PROGRAM,
553 (address >> 16) & 0xff,
554 (address >> 8) & 0xff,
555 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000556 byte
557 };
558
559 /* Send Byte-Program */
Peter Stugef83221b2008-07-07 06:38:51 +0000560 spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000561}
562
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000563int spi_disable_blockprotect(void)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000564{
565 uint8_t status;
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000566 int result;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000567
Peter Stugefa8c5502008-05-10 23:07:52 +0000568 status = spi_read_status_register();
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000569 /* If there is block protection in effect, unprotect it first. */
570 if ((status & 0x3c) != 0) {
571 printf_debug("Some block protection in effect, disabling\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000572 result = spi_write_status_enable();
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000573 if (result) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000574 printf_debug("spi_write_status_enable failed\n");
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000575 return result;
576 }
577 result = spi_write_status_register(status & ~0x3c);
578 if (result) {
579 printf_debug("spi_write_status_register failed\n");
580 return result;
581 }
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000582 }
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000583 return 0;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000584}
585
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000586int spi_nbyte_read(int address, uint8_t *bytes, int len)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000587{
Uwe Hermann394131e2008-10-18 21:14:13 +0000588 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
589 JEDEC_READ,
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000590 (address >> 16) & 0xff,
591 (address >> 8) & 0xff,
592 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000593 };
594
595 /* Send Read */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000596 return spi_command(sizeof(cmd), len, cmd, bytes);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000597}
598
Peter Stugefa8c5502008-05-10 23:07:52 +0000599int spi_chip_read(struct flashchip *flash, uint8_t *buf)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000600{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000601 switch (flashbus) {
602 case BUS_TYPE_IT87XX_SPI:
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000603 return it8716f_spi_chip_read(flash, buf);
Jason Wanga3f04be2008-11-28 21:36:51 +0000604 case BUS_TYPE_SB600_SPI:
605 return sb600_spi_read(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000606 case BUS_TYPE_ICH7_SPI:
607 case BUS_TYPE_ICH9_SPI:
608 case BUS_TYPE_VIA_SPI:
Rudolf Marek3fdbccf2008-06-30 21:38:30 +0000609 return ich_spi_read(flash, buf);
Peter Stugebf196e92009-01-26 03:08:45 +0000610 case BUS_TYPE_WBSIO_SPI:
611 return wbsio_spi_read(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000612 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000613 printf_debug
614 ("%s called, but no SPI chipset/strapping detected\n",
615 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000616 }
617
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000618 return 1;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000619}
620
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000621/*
622 * Program chip using byte programming. (SLOW!)
623 * This is for chips which can only handle one byte writes
624 * and for chips where memory mapped programming is impossible
625 * (e.g. due to size constraints in IT87* for over 512 kB)
626 */
627int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
628{
629 int total_size = 1024 * flash->total_size;
630 int i;
631
632 spi_disable_blockprotect();
633 for (i = 0; i < total_size; i++) {
634 spi_write_enable();
635 spi_byte_program(i, buf[i]);
636 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
637 myusec_delay(10);
638 }
639
640 return 0;
641}
642
643/*
644 * Program chip using page (256 bytes) programming.
645 * Some SPI masters can't do this, they use single byte programming instead.
646 */
Carl-Daniel Hailfinger8d497012009-05-09 02:34:18 +0000647int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000648{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000649 switch (flashbus) {
650 case BUS_TYPE_IT87XX_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000651 return it8716f_spi_chip_write_256(flash, buf);
Jason Wanga3f04be2008-11-28 21:36:51 +0000652 case BUS_TYPE_SB600_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000653 return sb600_spi_write_1(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000654 case BUS_TYPE_ICH7_SPI:
655 case BUS_TYPE_ICH9_SPI:
656 case BUS_TYPE_VIA_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000657 return ich_spi_write_256(flash, buf);
Peter Stugebf196e92009-01-26 03:08:45 +0000658 case BUS_TYPE_WBSIO_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000659 return wbsio_spi_write_1(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000660 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000661 printf_debug
662 ("%s called, but no SPI chipset/strapping detected\n",
663 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000664 }
665
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000666 return 1;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000667}
Peter Stugefd9217d2009-01-26 03:37:40 +0000668
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000669int spi_aai_write(struct flashchip *flash, uint8_t *buf)
670{
Peter Stugefd9217d2009-01-26 03:37:40 +0000671 uint32_t pos = 2, size = flash->total_size * 1024;
672 unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000673 int result;
674
Peter Stugefd9217d2009-01-26 03:37:40 +0000675 switch (flashbus) {
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000676 case BUS_TYPE_WBSIO_SPI:
677 fprintf(stderr, "%s: impossible with Winbond SPI masters,"
678 " degrading to byte program\n", __func__);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000679 return spi_chip_write_1(flash, buf);
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000680 default:
681 break;
Peter Stugefd9217d2009-01-26 03:37:40 +0000682 }
683 flash->erase(flash);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000684 result = spi_write_enable();
685 if (result)
686 return result;
Peter Stugefd9217d2009-01-26 03:37:40 +0000687 spi_command(6, 0, w, NULL);
688 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
689 myusec_delay(5); /* SST25VF040B Tbp is max 10us */
690 while (pos < size) {
691 w[1] = buf[pos++];
692 w[2] = buf[pos++];
693 spi_command(3, 0, w, NULL);
694 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
695 myusec_delay(5); /* SST25VF040B Tbp is max 10us */
696 }
697 spi_write_disable();
698 return 0;
699}