blob: fa29fb63c38e442f0343d1d79da3116cf9cd2857 [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
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000025#include <string.h>
26#include "flash.h"
Carl-Daniel Hailfingerd6cbf762008-05-13 14:58:23 +000027#include "spi.h"
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000028
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +000029void spi_prettyprint_status_register(struct flashchip *flash);
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000030
Uwe Hermann394131e2008-10-18 21:14:13 +000031int spi_command(unsigned int writecnt, unsigned int readcnt,
32 const unsigned char *writearr, unsigned char *readarr)
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000033{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000034 switch (flashbus) {
35 case BUS_TYPE_IT87XX_SPI:
Uwe Hermann394131e2008-10-18 21:14:13 +000036 return it8716f_spi_command(writecnt, readcnt, writearr,
37 readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000038 case BUS_TYPE_ICH7_SPI:
39 case BUS_TYPE_ICH9_SPI:
40 case BUS_TYPE_VIA_SPI:
Uwe Hermann394131e2008-10-18 21:14:13 +000041 return ich_spi_command(writecnt, readcnt, writearr, readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +000042 case BUS_TYPE_SB600_SPI:
43 return sb600_spi_command(writecnt, readcnt, writearr, readarr);
Peter Stugebf196e92009-01-26 03:08:45 +000044 case BUS_TYPE_WBSIO_SPI:
45 return wbsio_spi_command(writecnt, readcnt, writearr, readarr);
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000046 case BUS_TYPE_DUMMY_SPI:
47 return dummy_spi_command(writecnt, readcnt, writearr, readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000048 default:
Uwe Hermann394131e2008-10-18 21:14:13 +000049 printf_debug
50 ("%s called, but no SPI chipset/strapping detected\n",
51 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000052 }
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000053 return 1;
54}
55
Rudolf Marek48a85e42008-06-30 21:45:17 +000056static int spi_rdid(unsigned char *readarr, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000057{
Uwe Hermann394131e2008-10-18 21:14:13 +000058 const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000059 int ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000060 int i;
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000061
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000062 ret = spi_command(sizeof(cmd), bytes, cmd, readarr);
63 if (ret)
64 return ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000065 printf_debug("RDID returned");
66 for (i = 0; i < bytes; i++)
67 printf_debug(" 0x%02x", readarr[i]);
68 printf_debug("\n");
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000069 return 0;
70}
71
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000072static int spi_rems(unsigned char *readarr)
73{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000074 unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
75 uint32_t readaddr;
76 int ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000077
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000078 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
79 if (ret == SPI_INVALID_ADDRESS) {
80 /* Find the lowest even address allowed for reads. */
81 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
82 cmd[1] = (readaddr >> 16) & 0xff,
83 cmd[2] = (readaddr >> 8) & 0xff,
84 cmd[3] = (readaddr >> 0) & 0xff,
85 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
86 }
87 if (ret)
88 return ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000089 printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
90 return 0;
91}
92
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000093static int spi_res(unsigned char *readarr)
94{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000095 unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
96 uint32_t readaddr;
97 int ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000098
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000099 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
100 if (ret == SPI_INVALID_ADDRESS) {
101 /* Find the lowest even address allowed for reads. */
102 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
103 cmd[1] = (readaddr >> 16) & 0xff,
104 cmd[2] = (readaddr >> 8) & 0xff,
105 cmd[3] = (readaddr >> 0) & 0xff,
106 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
107 }
108 if (ret)
109 return ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000110 printf_debug("RES returned %02x.\n", readarr[0]);
111 return 0;
112}
113
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000114int spi_write_enable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000115{
Uwe Hermann394131e2008-10-18 21:14:13 +0000116 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000117 int result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000118
119 /* Send WREN (Write Enable) */
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000120 result = spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000121
122 if (result)
123 printf_debug("%s failed", __func__);
124 if (result == SPI_INVALID_OPCODE) {
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000125 switch (flashbus) {
126 case BUS_TYPE_ICH7_SPI:
127 case BUS_TYPE_ICH9_SPI:
128 case BUS_TYPE_VIA_SPI:
129 printf_debug(" due to SPI master limitation, ignoring"
130 " and hoping it will be run as PREOP\n");
131 return 0;
132 default:
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000133 break;
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000134 }
135 }
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000136 if (result)
137 printf_debug("\n");
138
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000139 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000140}
141
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000142int spi_write_disable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000143{
Uwe Hermann394131e2008-10-18 21:14:13 +0000144 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000145
146 /* Send WRDI (Write Disable) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000147 return spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000148}
149
Rudolf Marek48a85e42008-06-30 21:45:17 +0000150static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000151{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000152 unsigned char readarr[4];
Carl-Daniel Hailfinger1263d2a2008-02-06 22:07:58 +0000153 uint32_t manuf_id;
154 uint32_t model_id;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000155
Rudolf Marek48a85e42008-06-30 21:45:17 +0000156 if (spi_rdid(readarr, bytes))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000157 return 0;
158
159 if (!oddparity(readarr[0]))
160 printf_debug("RDID byte 0 parity violation.\n");
161
162 /* Check if this is a continuation vendor ID */
163 if (readarr[0] == 0x7f) {
164 if (!oddparity(readarr[1]))
165 printf_debug("RDID byte 1 parity violation.\n");
166 manuf_id = (readarr[0] << 8) | readarr[1];
167 model_id = readarr[2];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000168 if (bytes > 3) {
169 model_id <<= 8;
170 model_id |= readarr[3];
171 }
Peter Stugeda4e5f32008-06-24 01:22:03 +0000172 } else {
173 manuf_id = readarr[0];
174 model_id = (readarr[1] << 8) | readarr[2];
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000175 }
176
Peter Stuge5cafc332009-01-25 23:52:45 +0000177 printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, manuf_id,
Uwe Hermann394131e2008-10-18 21:14:13 +0000178 model_id);
Peter Stugeda4e5f32008-06-24 01:22:03 +0000179
Uwe Hermann394131e2008-10-18 21:14:13 +0000180 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
Peter Stugeda4e5f32008-06-24 01:22:03 +0000181 /* Print the status register to tell the
182 * user about possible write protection.
183 */
184 spi_prettyprint_status_register(flash);
185
186 return 1;
187 }
188
189 /* Test if this is a pure vendor match. */
190 if (manuf_id == flash->manufacture_id &&
191 GENERIC_DEVICE_ID == flash->model_id)
192 return 1;
193
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000194 return 0;
195}
196
Uwe Hermann394131e2008-10-18 21:14:13 +0000197int probe_spi_rdid(struct flashchip *flash)
198{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000199 return probe_spi_rdid_generic(flash, 3);
200}
201
202/* support 4 bytes flash ID */
Uwe Hermann394131e2008-10-18 21:14:13 +0000203int probe_spi_rdid4(struct flashchip *flash)
204{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000205 /* only some SPI chipsets support 4 bytes commands */
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000206 switch (flashbus) {
207 case BUS_TYPE_ICH7_SPI:
208 case BUS_TYPE_ICH9_SPI:
209 case BUS_TYPE_VIA_SPI:
Jason Wanga3f04be2008-11-28 21:36:51 +0000210 case BUS_TYPE_SB600_SPI:
Peter Stugebf196e92009-01-26 03:08:45 +0000211 case BUS_TYPE_WBSIO_SPI:
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +0000212 case BUS_TYPE_DUMMY_SPI:
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000213 return probe_spi_rdid_generic(flash, 4);
214 default:
215 printf_debug("4b ID not supported on this SPI controller\n");
216 }
217
218 return 0;
Rudolf Marek48a85e42008-06-30 21:45:17 +0000219}
220
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000221int probe_spi_rems(struct flashchip *flash)
222{
223 unsigned char readarr[JEDEC_REMS_INSIZE];
224 uint32_t manuf_id, model_id;
225
226 if (spi_rems(readarr))
227 return 0;
228
229 manuf_id = readarr[0];
230 model_id = readarr[1];
231
232 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id,
233 model_id);
234
235 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
236 /* Print the status register to tell the
237 * user about possible write protection.
238 */
239 spi_prettyprint_status_register(flash);
240
241 return 1;
242 }
243
244 /* Test if this is a pure vendor match. */
245 if (manuf_id == flash->manufacture_id &&
246 GENERIC_DEVICE_ID == flash->model_id)
247 return 1;
248
249 return 0;
250}
251
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000252int probe_spi_res(struct flashchip *flash)
253{
254 unsigned char readarr[3];
255 uint32_t model_id;
Peter Stugeda4e5f32008-06-24 01:22:03 +0000256
Carl-Daniel Hailfinger92a54ca2008-11-27 22:48:48 +0000257 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
258 * In that case, RES is pointless.
259 */
260 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
261 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000262 return 0;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000263
Peter Stugeda4e5f32008-06-24 01:22:03 +0000264 if (spi_res(readarr))
265 return 0;
266
267 model_id = readarr[0];
268 printf_debug("%s: id 0x%x\n", __FUNCTION__, model_id);
269 if (model_id != flash->model_id)
270 return 0;
271
272 /* Print the status register to tell the
273 * user about possible write protection.
274 */
275 spi_prettyprint_status_register(flash);
276 return 1;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000277}
278
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000279uint8_t spi_read_status_register(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000280{
Uwe Hermann394131e2008-10-18 21:14:13 +0000281 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
Peter Stugebf196e92009-01-26 03:08:45 +0000282 unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000283 int ret;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000284
285 /* Read Status Register */
Jason Wanga3f04be2008-11-28 21:36:51 +0000286 if (flashbus == BUS_TYPE_SB600_SPI) {
287 /* SB600 uses a different way to read status register. */
288 return sb600_read_status_register();
289 } else {
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000290 ret = spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
291 if (ret)
292 printf_debug("RDSR failed!\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000293 }
294
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000295 return readarr[0];
296}
297
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000298/* Prettyprint the status register. Common definitions. */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000299void spi_prettyprint_status_register_common(uint8_t status)
300{
301 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000302 "%sset\n", (status & (1 << 5)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000303 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000304 "%sset\n", (status & (1 << 4)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000305 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000306 "%sset\n", (status & (1 << 3)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000307 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000308 "%sset\n", (status & (1 << 2)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000309 printf_debug("Chip status register: Write Enable Latch (WEL) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000310 "%sset\n", (status & (1 << 1)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000311 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000312 "%sset\n", (status & (1 << 0)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000313}
314
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000315/* Prettyprint the status register. Works for
316 * ST M25P series
317 * MX MX25L series
318 */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000319void spi_prettyprint_status_register_st_m25p(uint8_t status)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000320{
321 printf_debug("Chip status register: Status Register Write Disable "
Uwe Hermann394131e2008-10-18 21:14:13 +0000322 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000323 printf_debug("Chip status register: Bit 6 is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000324 "%sset\n", (status & (1 << 6)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000325 spi_prettyprint_status_register_common(status);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000326}
327
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000328void spi_prettyprint_status_register_sst25(uint8_t status)
329{
330 printf_debug("Chip status register: Block Protect Write Disable "
331 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
332 printf_debug("Chip status register: Auto Address Increment Programming "
333 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
334 spi_prettyprint_status_register_common(status);
335}
336
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000337/* Prettyprint the status register. Works for
338 * SST 25VF016
339 */
340void spi_prettyprint_status_register_sst25vf016(uint8_t status)
341{
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000342 const char *bpt[] = {
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000343 "none",
344 "1F0000H-1FFFFFH",
345 "1E0000H-1FFFFFH",
346 "1C0000H-1FFFFFH",
347 "180000H-1FFFFFH",
348 "100000H-1FFFFFH",
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000349 "all", "all"
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000350 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000351 spi_prettyprint_status_register_sst25(status);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000352 printf_debug("Resulting block protection : %s\n",
Uwe Hermann394131e2008-10-18 21:14:13 +0000353 bpt[(status & 0x1c) >> 2]);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000354}
355
Peter Stuge5fecee42009-01-26 03:23:50 +0000356void spi_prettyprint_status_register_sst25vf040b(uint8_t status)
357{
358 const char *bpt[] = {
359 "none",
360 "0x70000-0x7ffff",
361 "0x60000-0x7ffff",
362 "0x40000-0x7ffff",
363 "all blocks", "all blocks", "all blocks", "all blocks"
364 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000365 spi_prettyprint_status_register_sst25(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000366 printf_debug("Resulting block protection : %s\n",
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000367 bpt[(status & 0x1c) >> 2]);
Peter Stuge5fecee42009-01-26 03:23:50 +0000368}
369
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000370void spi_prettyprint_status_register(struct flashchip *flash)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000371{
372 uint8_t status;
373
Peter Stugefa8c5502008-05-10 23:07:52 +0000374 status = spi_read_status_register();
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000375 printf_debug("Chip status register is %02x\n", status);
376 switch (flash->manufacture_id) {
377 case ST_ID:
Carl-Daniel Hailfingerf43e6422008-05-15 22:32:08 +0000378 if (((flash->model_id & 0xff00) == 0x2000) ||
379 ((flash->model_id & 0xff00) == 0x2500))
380 spi_prettyprint_status_register_st_m25p(status);
381 break;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000382 case MX_ID:
383 if ((flash->model_id & 0xff00) == 0x2000)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000384 spi_prettyprint_status_register_st_m25p(status);
385 break;
386 case SST_ID:
Peter Stuge5fecee42009-01-26 03:23:50 +0000387 switch (flash->model_id) {
388 case 0x2541:
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000389 spi_prettyprint_status_register_sst25vf016(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000390 break;
391 case 0x8d:
392 case 0x258d:
393 spi_prettyprint_status_register_sst25vf040b(status);
394 break;
Carl-Daniel Hailfinger5100a8a2009-05-13 22:51:27 +0000395 default:
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000396 spi_prettyprint_status_register_sst25(status);
397 break;
Peter Stuge5fecee42009-01-26 03:23:50 +0000398 }
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000399 break;
400 }
401}
Uwe Hermann394131e2008-10-18 21:14:13 +0000402
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000403int spi_chip_erase_60(struct flashchip *flash)
404{
405 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000406 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000407
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000408 result = spi_disable_blockprotect();
409 if (result) {
410 printf_debug("spi_disable_blockprotect failed\n");
411 return result;
412 }
413 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000414 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000415 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000416 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000417 result = spi_command(sizeof(cmd), 0, cmd, NULL);
418 if (result) {
419 printf_debug("spi_chip_erase_60 failed sending erase\n");
420 return result;
421 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000422 /* Wait until the Write-In-Progress bit is cleared.
423 * This usually takes 1-85 s, so wait in 1 s steps.
424 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000425 /* FIXME: We assume spi_read_status_register will never fail. */
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000426 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
427 sleep(1);
428 return 0;
429}
430
Peter Stugefa8c5502008-05-10 23:07:52 +0000431int spi_chip_erase_c7(struct flashchip *flash)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000432{
Uwe Hermann394131e2008-10-18 21:14:13 +0000433 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000434 int result;
Uwe Hermann394131e2008-10-18 21:14:13 +0000435
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000436 result = spi_disable_blockprotect();
437 if (result) {
438 printf_debug("spi_disable_blockprotect failed\n");
439 return result;
440 }
441 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000442 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000443 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000444 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000445 result = spi_command(sizeof(cmd), 0, cmd, NULL);
446 if (result) {
447 printf_debug("spi_chip_erase_60 failed sending erase\n");
448 return result;
449 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000450 /* Wait until the Write-In-Progress bit is cleared.
451 * This usually takes 1-85 s, so wait in 1 s steps.
452 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000453 /* FIXME: We assume spi_read_status_register will never fail. */
Peter Stugefa8c5502008-05-10 23:07:52 +0000454 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000455 sleep(1);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000456 return 0;
457}
458
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000459int spi_chip_erase_60_c7(struct flashchip *flash)
460{
461 int result;
462 result = spi_chip_erase_60(flash);
463 if (result) {
464 printf_debug("spi_chip_erase_60 failed, trying c7\n");
465 result = spi_chip_erase_c7(flash);
466 }
467 return result;
468}
469
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000470int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
471{
472 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000473 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000474
475 cmd[1] = (addr & 0x00ff0000) >> 16;
476 cmd[2] = (addr & 0x0000ff00) >> 8;
477 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000478 result = spi_write_enable();
479 if (result)
480 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000481 /* Send BE (Block Erase) */
482 spi_command(sizeof(cmd), 0, cmd, NULL);
483 /* Wait until the Write-In-Progress bit is cleared.
484 * This usually takes 100-4000 ms, so wait in 100 ms steps.
485 */
486 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
487 usleep(100 * 1000);
488 return 0;
489}
490
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000491/* Block size is usually
492 * 64k for Macronix
493 * 32k for SST
494 * 4-32k non-uniform for EON
495 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000496int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000497{
Uwe Hermann394131e2008-10-18 21:14:13 +0000498 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000499 int result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000500
501 cmd[1] = (addr & 0x00ff0000) >> 16;
502 cmd[2] = (addr & 0x0000ff00) >> 8;
503 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000504 result = spi_write_enable();
505 if (result)
506 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000507 /* Send BE (Block Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000508 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000509 /* Wait until the Write-In-Progress bit is cleared.
510 * This usually takes 100-4000 ms, so wait in 100 ms steps.
511 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000512 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000513 usleep(100 * 1000);
514 return 0;
515}
516
Stefan Reinauer424ed222008-10-29 22:13:20 +0000517int spi_chip_erase_d8(struct flashchip *flash)
518{
519 int i, rc = 0;
520 int total_size = flash->total_size * 1024;
521 int erase_size = 64 * 1024;
522
523 spi_disable_blockprotect();
524
525 printf("Erasing chip: \n");
526
527 for (i = 0; i < total_size / erase_size; i++) {
528 rc = spi_block_erase_d8(flash, i * erase_size);
529 if (rc) {
530 printf("Error erasing block at 0x%x\n", i);
531 break;
532 }
533 }
534
535 printf("\n");
536
537 return rc;
538}
539
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000540/* Sector size is usually 4k, though Macronix eliteflash has 64k */
Peter Stugefa8c5502008-05-10 23:07:52 +0000541int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000542{
Uwe Hermann394131e2008-10-18 21:14:13 +0000543 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000544 int result;
545
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000546 cmd[1] = (addr & 0x00ff0000) >> 16;
547 cmd[2] = (addr & 0x0000ff00) >> 8;
548 cmd[3] = (addr & 0x000000ff);
549
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000550 result = spi_write_enable();
551 if (result)
552 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000553 /* Send SE (Sector Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000554 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000555 /* Wait until the Write-In-Progress bit is cleared.
556 * This usually takes 15-800 ms, so wait in 10 ms steps.
557 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000558 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000559 usleep(10 * 1000);
560 return 0;
561}
562
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000563int spi_write_status_enable(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000564{
565 const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000566 int result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000567
568 /* Send EWSR (Enable Write Status Register). */
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000569 result = spi_command(sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
570
571 if (result)
572 printf_debug("%s failed", __func__);
573 if (result == SPI_INVALID_OPCODE) {
574 switch (flashbus) {
575 case BUS_TYPE_ICH7_SPI:
576 case BUS_TYPE_ICH9_SPI:
577 case BUS_TYPE_VIA_SPI:
578 printf_debug(" due to SPI master limitation, ignoring"
579 " and hoping it will be run as PREOP\n");
580 return 0;
581 default:
582 break;
583 }
584 }
585 if (result)
586 printf_debug("\n");
587
588 return result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000589}
590
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000591/*
592 * This is according the SST25VF016 datasheet, who knows it is more
593 * generic that this...
594 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000595int spi_write_status_register(int status)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000596{
Uwe Hermann394131e2008-10-18 21:14:13 +0000597 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
598 { JEDEC_WRSR, (unsigned char)status };
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000599
600 /* Send WRSR (Write Status Register) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000601 return spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000602}
603
604void spi_byte_program(int address, uint8_t byte)
605{
Uwe Hermann394131e2008-10-18 21:14:13 +0000606 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
607 JEDEC_BYTE_PROGRAM,
608 (address >> 16) & 0xff,
609 (address >> 8) & 0xff,
610 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000611 byte
612 };
613
614 /* Send Byte-Program */
Peter Stugef83221b2008-07-07 06:38:51 +0000615 spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000616}
617
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000618int spi_disable_blockprotect(void)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000619{
620 uint8_t status;
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000621 int result;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000622
Peter Stugefa8c5502008-05-10 23:07:52 +0000623 status = spi_read_status_register();
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000624 /* If there is block protection in effect, unprotect it first. */
625 if ((status & 0x3c) != 0) {
626 printf_debug("Some block protection in effect, disabling\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000627 result = spi_write_status_enable();
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000628 if (result) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000629 printf_debug("spi_write_status_enable failed\n");
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000630 return result;
631 }
632 result = spi_write_status_register(status & ~0x3c);
633 if (result) {
634 printf_debug("spi_write_status_register failed\n");
635 return result;
636 }
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000637 }
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000638 return 0;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000639}
640
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000641int spi_nbyte_read(int address, uint8_t *bytes, int len)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000642{
Uwe Hermann394131e2008-10-18 21:14:13 +0000643 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
644 JEDEC_READ,
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000645 (address >> 16) & 0xff,
646 (address >> 8) & 0xff,
647 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000648 };
649
650 /* Send Read */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000651 return spi_command(sizeof(cmd), len, cmd, bytes);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000652}
653
Peter Stugefa8c5502008-05-10 23:07:52 +0000654int spi_chip_read(struct flashchip *flash, uint8_t *buf)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000655{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000656 switch (flashbus) {
657 case BUS_TYPE_IT87XX_SPI:
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000658 return it8716f_spi_chip_read(flash, buf);
Jason Wanga3f04be2008-11-28 21:36:51 +0000659 case BUS_TYPE_SB600_SPI:
660 return sb600_spi_read(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000661 case BUS_TYPE_ICH7_SPI:
662 case BUS_TYPE_ICH9_SPI:
663 case BUS_TYPE_VIA_SPI:
Rudolf Marek3fdbccf2008-06-30 21:38:30 +0000664 return ich_spi_read(flash, buf);
Peter Stugebf196e92009-01-26 03:08:45 +0000665 case BUS_TYPE_WBSIO_SPI:
666 return wbsio_spi_read(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000667 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000668 printf_debug
669 ("%s called, but no SPI chipset/strapping detected\n",
670 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000671 }
672
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000673 return 1;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000674}
675
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000676/*
677 * Program chip using byte programming. (SLOW!)
678 * This is for chips which can only handle one byte writes
679 * and for chips where memory mapped programming is impossible
680 * (e.g. due to size constraints in IT87* for over 512 kB)
681 */
682int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
683{
684 int total_size = 1024 * flash->total_size;
685 int i;
686
687 spi_disable_blockprotect();
688 for (i = 0; i < total_size; i++) {
689 spi_write_enable();
690 spi_byte_program(i, buf[i]);
691 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
692 myusec_delay(10);
693 }
694
695 return 0;
696}
697
698/*
699 * Program chip using page (256 bytes) programming.
700 * Some SPI masters can't do this, they use single byte programming instead.
701 */
Carl-Daniel Hailfinger8d497012009-05-09 02:34:18 +0000702int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000703{
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000704 switch (flashbus) {
705 case BUS_TYPE_IT87XX_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000706 return it8716f_spi_chip_write_256(flash, buf);
Jason Wanga3f04be2008-11-28 21:36:51 +0000707 case BUS_TYPE_SB600_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000708 return sb600_spi_write_1(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000709 case BUS_TYPE_ICH7_SPI:
710 case BUS_TYPE_ICH9_SPI:
711 case BUS_TYPE_VIA_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000712 return ich_spi_write_256(flash, buf);
Peter Stugebf196e92009-01-26 03:08:45 +0000713 case BUS_TYPE_WBSIO_SPI:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000714 return wbsio_spi_write_1(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000715 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000716 printf_debug
717 ("%s called, but no SPI chipset/strapping detected\n",
718 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000719 }
720
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000721 return 1;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000722}
Peter Stugefd9217d2009-01-26 03:37:40 +0000723
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000724uint32_t spi_get_valid_read_addr(void)
725{
726 /* Need to return BBAR for ICH chipsets. */
727 return 0;
728}
729
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000730int spi_aai_write(struct flashchip *flash, uint8_t *buf)
731{
Peter Stugefd9217d2009-01-26 03:37:40 +0000732 uint32_t pos = 2, size = flash->total_size * 1024;
733 unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000734 int result;
735
Peter Stugefd9217d2009-01-26 03:37:40 +0000736 switch (flashbus) {
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000737 case BUS_TYPE_WBSIO_SPI:
738 fprintf(stderr, "%s: impossible with Winbond SPI masters,"
739 " degrading to byte program\n", __func__);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000740 return spi_chip_write_1(flash, buf);
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000741 default:
742 break;
Peter Stugefd9217d2009-01-26 03:37:40 +0000743 }
744 flash->erase(flash);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000745 result = spi_write_enable();
746 if (result)
747 return result;
Peter Stugefd9217d2009-01-26 03:37:40 +0000748 spi_command(6, 0, w, NULL);
749 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
750 myusec_delay(5); /* SST25VF040B Tbp is max 10us */
751 while (pos < size) {
752 w[1] = buf[pos++];
753 w[2] = buf[pos++];
754 spi_command(3, 0, w, NULL);
755 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
756 myusec_delay(5); /* SST25VF040B Tbp is max 10us */
757 }
758 spi_write_disable();
759 return 0;
760}