blob: 3160754dc3a807a64cb1448959746667634a38c8 [file] [log] [blame]
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +00001/*
2 * This file is part of the flashrom project.
3 *
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +00004 * Copyright (C) 2007, 2008, 2009 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 Hailfinger08454642009-06-15 14:14:48 +000027#include "flashchips.h"
Carl-Daniel Hailfingerd6cbf762008-05-13 14:58:23 +000028#include "spi.h"
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000029
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000030enum spi_controller spi_controller = SPI_CONTROLLER_NONE;
31void *spibar = NULL;
32
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +000033void spi_prettyprint_status_register(struct flashchip *flash);
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000034
Uwe Hermann394131e2008-10-18 21:14:13 +000035int spi_command(unsigned int writecnt, unsigned int readcnt,
36 const unsigned char *writearr, unsigned char *readarr)
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000037{
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000038 switch (spi_controller) {
39 case SPI_CONTROLLER_IT87XX:
Uwe Hermann394131e2008-10-18 21:14:13 +000040 return it8716f_spi_command(writecnt, readcnt, writearr,
41 readarr);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000042 case SPI_CONTROLLER_ICH7:
43 case SPI_CONTROLLER_ICH9:
44 case SPI_CONTROLLER_VIA:
Uwe Hermann394131e2008-10-18 21:14:13 +000045 return ich_spi_command(writecnt, readcnt, writearr, readarr);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000046 case SPI_CONTROLLER_SB600:
Jason Wanga3f04be2008-11-28 21:36:51 +000047 return sb600_spi_command(writecnt, readcnt, writearr, readarr);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000048 case SPI_CONTROLLER_WBSIO:
Peter Stugebf196e92009-01-26 03:08:45 +000049 return wbsio_spi_command(writecnt, readcnt, writearr, readarr);
Paul Fox05dfbe62009-06-16 21:08:06 +000050 case SPI_CONTROLLER_FT2232:
51 return ft2232_spi_command(writecnt, readcnt, writearr, readarr);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000052 case SPI_CONTROLLER_DUMMY:
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000053 return dummy_spi_command(writecnt, readcnt, writearr, readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000054 default:
Uwe Hermann394131e2008-10-18 21:14:13 +000055 printf_debug
56 ("%s called, but no SPI chipset/strapping detected\n",
57 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000058 }
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000059 return 1;
60}
61
Rudolf Marek48a85e42008-06-30 21:45:17 +000062static int spi_rdid(unsigned char *readarr, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000063{
Uwe Hermann394131e2008-10-18 21:14:13 +000064 const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000065 int ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000066 int i;
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000067
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000068 ret = spi_command(sizeof(cmd), bytes, cmd, readarr);
69 if (ret)
70 return ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000071 printf_debug("RDID returned");
72 for (i = 0; i < bytes; i++)
73 printf_debug(" 0x%02x", readarr[i]);
74 printf_debug("\n");
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000075 return 0;
76}
77
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000078static int spi_rems(unsigned char *readarr)
79{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000080 unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
81 uint32_t readaddr;
82 int ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000083
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000084 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
85 if (ret == SPI_INVALID_ADDRESS) {
86 /* Find the lowest even address allowed for reads. */
87 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
88 cmd[1] = (readaddr >> 16) & 0xff,
89 cmd[2] = (readaddr >> 8) & 0xff,
90 cmd[3] = (readaddr >> 0) & 0xff,
91 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
92 }
93 if (ret)
94 return ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000095 printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
96 return 0;
97}
98
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000099static int spi_res(unsigned char *readarr)
100{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000101 unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
102 uint32_t readaddr;
103 int ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000104
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000105 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
106 if (ret == SPI_INVALID_ADDRESS) {
107 /* Find the lowest even address allowed for reads. */
108 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
109 cmd[1] = (readaddr >> 16) & 0xff,
110 cmd[2] = (readaddr >> 8) & 0xff,
111 cmd[3] = (readaddr >> 0) & 0xff,
112 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
113 }
114 if (ret)
115 return ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000116 printf_debug("RES returned %02x.\n", readarr[0]);
117 return 0;
118}
119
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000120int spi_write_enable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000121{
Uwe Hermann394131e2008-10-18 21:14:13 +0000122 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000123 int result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000124
125 /* Send WREN (Write Enable) */
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000126 result = spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000127
128 if (result)
129 printf_debug("%s failed", __func__);
130 if (result == SPI_INVALID_OPCODE) {
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000131 switch (spi_controller) {
132 case SPI_CONTROLLER_ICH7:
133 case SPI_CONTROLLER_ICH9:
134 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000135 printf_debug(" due to SPI master limitation, ignoring"
136 " and hoping it will be run as PREOP\n");
137 return 0;
138 default:
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000139 break;
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000140 }
141 }
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000142 if (result)
143 printf_debug("\n");
144
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000145 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000146}
147
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000148int spi_write_disable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000149{
Uwe Hermann394131e2008-10-18 21:14:13 +0000150 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000151
152 /* Send WRDI (Write Disable) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000153 return spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000154}
155
Rudolf Marek48a85e42008-06-30 21:45:17 +0000156static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000157{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000158 unsigned char readarr[4];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000159 uint32_t id1;
160 uint32_t id2;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000161
Rudolf Marek48a85e42008-06-30 21:45:17 +0000162 if (spi_rdid(readarr, bytes))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000163 return 0;
164
165 if (!oddparity(readarr[0]))
166 printf_debug("RDID byte 0 parity violation.\n");
167
168 /* Check if this is a continuation vendor ID */
169 if (readarr[0] == 0x7f) {
170 if (!oddparity(readarr[1]))
171 printf_debug("RDID byte 1 parity violation.\n");
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000172 id1 = (readarr[0] << 8) | readarr[1];
173 id2 = readarr[2];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000174 if (bytes > 3) {
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000175 id2 <<= 8;
176 id2 |= readarr[3];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000177 }
Peter Stugeda4e5f32008-06-24 01:22:03 +0000178 } else {
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000179 id1 = readarr[0];
180 id2 = (readarr[1] << 8) | readarr[2];
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000181 }
182
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000183 printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2);
Peter Stugeda4e5f32008-06-24 01:22:03 +0000184
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000185 if (id1 == flash->manufacture_id && id2 == flash->model_id) {
Peter Stugeda4e5f32008-06-24 01:22:03 +0000186 /* Print the status register to tell the
187 * user about possible write protection.
188 */
189 spi_prettyprint_status_register(flash);
190
191 return 1;
192 }
193
194 /* Test if this is a pure vendor match. */
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000195 if (id1 == flash->manufacture_id &&
Peter Stugeda4e5f32008-06-24 01:22:03 +0000196 GENERIC_DEVICE_ID == flash->model_id)
197 return 1;
198
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000199 return 0;
200}
201
Uwe Hermann394131e2008-10-18 21:14:13 +0000202int probe_spi_rdid(struct flashchip *flash)
203{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000204 return probe_spi_rdid_generic(flash, 3);
205}
206
207/* support 4 bytes flash ID */
Uwe Hermann394131e2008-10-18 21:14:13 +0000208int probe_spi_rdid4(struct flashchip *flash)
209{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000210 /* only some SPI chipsets support 4 bytes commands */
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000211 switch (spi_controller) {
212 case SPI_CONTROLLER_ICH7:
213 case SPI_CONTROLLER_ICH9:
214 case SPI_CONTROLLER_VIA:
215 case SPI_CONTROLLER_SB600:
216 case SPI_CONTROLLER_WBSIO:
Paul Fox05dfbe62009-06-16 21:08:06 +0000217 case SPI_CONTROLLER_FT2232:
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000218 case SPI_CONTROLLER_DUMMY:
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000219 return probe_spi_rdid_generic(flash, 4);
220 default:
221 printf_debug("4b ID not supported on this SPI controller\n");
222 }
223
224 return 0;
Rudolf Marek48a85e42008-06-30 21:45:17 +0000225}
226
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000227int probe_spi_rems(struct flashchip *flash)
228{
229 unsigned char readarr[JEDEC_REMS_INSIZE];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000230 uint32_t id1, id2;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000231
232 if (spi_rems(readarr))
233 return 0;
234
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000235 id1 = readarr[0];
236 id2 = readarr[1];
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000237
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000238 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000239
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000240 if (id1 == flash->manufacture_id && id2 == flash->model_id) {
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000241 /* Print the status register to tell the
242 * user about possible write protection.
243 */
244 spi_prettyprint_status_register(flash);
245
246 return 1;
247 }
248
249 /* Test if this is a pure vendor match. */
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000250 if (id1 == flash->manufacture_id &&
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000251 GENERIC_DEVICE_ID == flash->model_id)
252 return 1;
253
254 return 0;
255}
256
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000257int probe_spi_res(struct flashchip *flash)
258{
259 unsigned char readarr[3];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000260 uint32_t id2;
Peter Stugeda4e5f32008-06-24 01:22:03 +0000261
Carl-Daniel Hailfinger92a54ca2008-11-27 22:48:48 +0000262 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
263 * In that case, RES is pointless.
264 */
265 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
266 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000267 return 0;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000268
Peter Stugeda4e5f32008-06-24 01:22:03 +0000269 if (spi_res(readarr))
270 return 0;
271
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000272 id2 = readarr[0];
273 printf_debug("%s: id 0x%x\n", __FUNCTION__, id2);
274 if (id2 != flash->model_id)
Peter Stugeda4e5f32008-06-24 01:22:03 +0000275 return 0;
276
277 /* Print the status register to tell the
278 * user about possible write protection.
279 */
280 spi_prettyprint_status_register(flash);
281 return 1;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000282}
283
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000284uint8_t spi_read_status_register(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000285{
Uwe Hermann394131e2008-10-18 21:14:13 +0000286 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
Peter Stugebf196e92009-01-26 03:08:45 +0000287 unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000288 int ret;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000289
290 /* Read Status Register */
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000291 if (spi_controller == SPI_CONTROLLER_SB600) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000292 /* SB600 uses a different way to read status register. */
293 return sb600_read_status_register();
294 } else {
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000295 ret = spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
296 if (ret)
297 printf_debug("RDSR failed!\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000298 }
299
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000300 return readarr[0];
301}
302
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000303/* Prettyprint the status register. Common definitions. */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000304void spi_prettyprint_status_register_common(uint8_t status)
305{
306 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000307 "%sset\n", (status & (1 << 5)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000308 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000309 "%sset\n", (status & (1 << 4)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000310 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000311 "%sset\n", (status & (1 << 3)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000312 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000313 "%sset\n", (status & (1 << 2)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000314 printf_debug("Chip status register: Write Enable Latch (WEL) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000315 "%sset\n", (status & (1 << 1)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000316 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000317 "%sset\n", (status & (1 << 0)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000318}
319
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000320/* Prettyprint the status register. Works for
321 * ST M25P series
322 * MX MX25L series
323 */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000324void spi_prettyprint_status_register_st_m25p(uint8_t status)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000325{
326 printf_debug("Chip status register: Status Register Write Disable "
Uwe Hermann394131e2008-10-18 21:14:13 +0000327 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000328 printf_debug("Chip status register: Bit 6 is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000329 "%sset\n", (status & (1 << 6)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000330 spi_prettyprint_status_register_common(status);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000331}
332
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000333void spi_prettyprint_status_register_sst25(uint8_t status)
334{
335 printf_debug("Chip status register: Block Protect Write Disable "
336 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
337 printf_debug("Chip status register: Auto Address Increment Programming "
338 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
339 spi_prettyprint_status_register_common(status);
340}
341
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000342/* Prettyprint the status register. Works for
343 * SST 25VF016
344 */
345void spi_prettyprint_status_register_sst25vf016(uint8_t status)
346{
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000347 const char *bpt[] = {
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000348 "none",
349 "1F0000H-1FFFFFH",
350 "1E0000H-1FFFFFH",
351 "1C0000H-1FFFFFH",
352 "180000H-1FFFFFH",
353 "100000H-1FFFFFH",
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000354 "all", "all"
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000355 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000356 spi_prettyprint_status_register_sst25(status);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000357 printf_debug("Resulting block protection : %s\n",
Uwe Hermann394131e2008-10-18 21:14:13 +0000358 bpt[(status & 0x1c) >> 2]);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000359}
360
Peter Stuge5fecee42009-01-26 03:23:50 +0000361void spi_prettyprint_status_register_sst25vf040b(uint8_t status)
362{
363 const char *bpt[] = {
364 "none",
365 "0x70000-0x7ffff",
366 "0x60000-0x7ffff",
367 "0x40000-0x7ffff",
368 "all blocks", "all blocks", "all blocks", "all blocks"
369 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000370 spi_prettyprint_status_register_sst25(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000371 printf_debug("Resulting block protection : %s\n",
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000372 bpt[(status & 0x1c) >> 2]);
Peter Stuge5fecee42009-01-26 03:23:50 +0000373}
374
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000375void spi_prettyprint_status_register(struct flashchip *flash)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000376{
377 uint8_t status;
378
Peter Stugefa8c5502008-05-10 23:07:52 +0000379 status = spi_read_status_register();
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000380 printf_debug("Chip status register is %02x\n", status);
381 switch (flash->manufacture_id) {
382 case ST_ID:
Carl-Daniel Hailfingerf43e6422008-05-15 22:32:08 +0000383 if (((flash->model_id & 0xff00) == 0x2000) ||
384 ((flash->model_id & 0xff00) == 0x2500))
385 spi_prettyprint_status_register_st_m25p(status);
386 break;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000387 case MX_ID:
388 if ((flash->model_id & 0xff00) == 0x2000)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000389 spi_prettyprint_status_register_st_m25p(status);
390 break;
391 case SST_ID:
Peter Stuge5fecee42009-01-26 03:23:50 +0000392 switch (flash->model_id) {
393 case 0x2541:
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000394 spi_prettyprint_status_register_sst25vf016(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000395 break;
396 case 0x8d:
397 case 0x258d:
398 spi_prettyprint_status_register_sst25vf040b(status);
399 break;
Carl-Daniel Hailfinger5100a8a2009-05-13 22:51:27 +0000400 default:
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000401 spi_prettyprint_status_register_sst25(status);
402 break;
Peter Stuge5fecee42009-01-26 03:23:50 +0000403 }
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000404 break;
405 }
406}
Uwe Hermann394131e2008-10-18 21:14:13 +0000407
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000408int spi_chip_erase_60(struct flashchip *flash)
409{
410 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000411 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000412
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000413 result = spi_disable_blockprotect();
414 if (result) {
415 printf_debug("spi_disable_blockprotect failed\n");
416 return result;
417 }
418 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000419 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000420 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000421 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000422 result = spi_command(sizeof(cmd), 0, cmd, NULL);
423 if (result) {
424 printf_debug("spi_chip_erase_60 failed sending erase\n");
425 return result;
426 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000427 /* Wait until the Write-In-Progress bit is cleared.
428 * This usually takes 1-85 s, so wait in 1 s steps.
429 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000430 /* FIXME: We assume spi_read_status_register will never fail. */
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000431 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000432 programmer_delay(1000 * 1000);
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000433 if (check_erased_range(flash, 0, flash->total_size * 1024)) {
434 fprintf(stderr, "ERASE FAILED!\n");
435 return -1;
436 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000437 return 0;
438}
439
Peter Stugefa8c5502008-05-10 23:07:52 +0000440int spi_chip_erase_c7(struct flashchip *flash)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000441{
Uwe Hermann394131e2008-10-18 21:14:13 +0000442 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000443 int result;
Uwe Hermann394131e2008-10-18 21:14:13 +0000444
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000445 result = spi_disable_blockprotect();
446 if (result) {
447 printf_debug("spi_disable_blockprotect failed\n");
448 return result;
449 }
450 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000451 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000452 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000453 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000454 result = spi_command(sizeof(cmd), 0, cmd, NULL);
455 if (result) {
456 printf_debug("spi_chip_erase_60 failed sending erase\n");
457 return result;
458 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000459 /* Wait until the Write-In-Progress bit is cleared.
460 * This usually takes 1-85 s, so wait in 1 s steps.
461 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000462 /* FIXME: We assume spi_read_status_register will never fail. */
Peter Stugefa8c5502008-05-10 23:07:52 +0000463 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000464 programmer_delay(1000 * 1000);
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000465 if (check_erased_range(flash, 0, flash->total_size * 1024)) {
466 fprintf(stderr, "ERASE FAILED!\n");
467 return -1;
468 }
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000469 return 0;
470}
471
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000472int spi_chip_erase_60_c7(struct flashchip *flash)
473{
474 int result;
475 result = spi_chip_erase_60(flash);
476 if (result) {
477 printf_debug("spi_chip_erase_60 failed, trying c7\n");
478 result = spi_chip_erase_c7(flash);
479 }
480 return result;
481}
482
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000483int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000484{
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000485 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52, };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000486 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000487
488 cmd[1] = (addr & 0x00ff0000) >> 16;
489 cmd[2] = (addr & 0x0000ff00) >> 8;
490 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000491 result = spi_write_enable();
492 if (result)
493 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000494 /* Send BE (Block Erase) */
495 spi_command(sizeof(cmd), 0, cmd, NULL);
496 /* Wait until the Write-In-Progress bit is cleared.
497 * This usually takes 100-4000 ms, so wait in 100 ms steps.
498 */
499 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000500 programmer_delay(100 * 1000);
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000501 if (check_erased_range(flash, addr, blocklen)) {
502 fprintf(stderr, "ERASE FAILED!\n");
503 return -1;
504 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000505 return 0;
506}
507
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000508/* Block size is usually
509 * 64k for Macronix
510 * 32k for SST
511 * 4-32k non-uniform for EON
512 */
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000513int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000514{
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000515 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8, };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000516 int result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000517
518 cmd[1] = (addr & 0x00ff0000) >> 16;
519 cmd[2] = (addr & 0x0000ff00) >> 8;
520 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000521 result = spi_write_enable();
522 if (result)
523 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000524 /* Send BE (Block Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000525 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000526 /* Wait until the Write-In-Progress bit is cleared.
527 * This usually takes 100-4000 ms, so wait in 100 ms steps.
528 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000529 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000530 programmer_delay(100 * 1000);
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000531 if (check_erased_range(flash, addr, blocklen)) {
532 fprintf(stderr, "ERASE FAILED!\n");
533 return -1;
534 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000535 return 0;
536}
537
Stefan Reinauer424ed222008-10-29 22:13:20 +0000538int spi_chip_erase_d8(struct flashchip *flash)
539{
540 int i, rc = 0;
541 int total_size = flash->total_size * 1024;
542 int erase_size = 64 * 1024;
543
544 spi_disable_blockprotect();
545
546 printf("Erasing chip: \n");
547
548 for (i = 0; i < total_size / erase_size; i++) {
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000549 rc = spi_block_erase_d8(flash, i * erase_size, erase_size);
Stefan Reinauer424ed222008-10-29 22:13:20 +0000550 if (rc) {
551 printf("Error erasing block at 0x%x\n", i);
552 break;
553 }
554 }
555
556 printf("\n");
557
558 return rc;
559}
560
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000561/* Sector size is usually 4k, though Macronix eliteflash has 64k */
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000562int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000563{
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000564 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE, };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000565 int result;
566
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000567 cmd[1] = (addr & 0x00ff0000) >> 16;
568 cmd[2] = (addr & 0x0000ff00) >> 8;
569 cmd[3] = (addr & 0x000000ff);
570
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000571 result = spi_write_enable();
572 if (result)
573 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000574 /* Send SE (Sector Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000575 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000576 /* Wait until the Write-In-Progress bit is cleared.
577 * This usually takes 15-800 ms, so wait in 10 ms steps.
578 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000579 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000580 programmer_delay(10 * 1000);
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000581 if (check_erased_range(flash, addr, blocklen)) {
582 fprintf(stderr, "ERASE FAILED!\n");
583 return -1;
584 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000585 return 0;
586}
587
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000588int spi_block_erase_60(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
589{
590 if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
591 fprintf(stderr, "%s called with incorrect arguments\n", __func__);
592 return -1;
593 }
594 return spi_chip_erase_60(flash);
595}
596
597int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
598{
599 if ((addr != 0) || (blocklen != flash->total_size * 1024)) {
600 fprintf(stderr, "%s called with incorrect arguments\n", __func__);
601 return -1;
602 }
603 return spi_chip_erase_c7(flash);
604}
605
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000606int spi_write_status_enable(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000607{
608 const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000609 int result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000610
611 /* Send EWSR (Enable Write Status Register). */
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000612 result = spi_command(sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
613
614 if (result)
615 printf_debug("%s failed", __func__);
616 if (result == SPI_INVALID_OPCODE) {
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000617 switch (spi_controller) {
618 case SPI_CONTROLLER_ICH7:
619 case SPI_CONTROLLER_ICH9:
620 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000621 printf_debug(" due to SPI master limitation, ignoring"
622 " and hoping it will be run as PREOP\n");
623 return 0;
624 default:
625 break;
626 }
627 }
628 if (result)
629 printf_debug("\n");
630
631 return result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000632}
633
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000634/*
635 * This is according the SST25VF016 datasheet, who knows it is more
636 * generic that this...
637 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000638int spi_write_status_register(int status)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000639{
Uwe Hermann394131e2008-10-18 21:14:13 +0000640 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
641 { JEDEC_WRSR, (unsigned char)status };
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000642
643 /* Send WRSR (Write Status Register) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000644 return spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000645}
646
647void spi_byte_program(int address, uint8_t byte)
648{
Uwe Hermann394131e2008-10-18 21:14:13 +0000649 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
650 JEDEC_BYTE_PROGRAM,
651 (address >> 16) & 0xff,
652 (address >> 8) & 0xff,
653 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000654 byte
655 };
656
657 /* Send Byte-Program */
Peter Stugef83221b2008-07-07 06:38:51 +0000658 spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000659}
660
Paul Foxeb3acef2009-06-12 08:10:33 +0000661int spi_nbyte_program(int address, uint8_t *bytes, int len)
662{
663 unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + 256] = {
664 JEDEC_BYTE_PROGRAM,
665 (address >> 16) & 0xff,
666 (address >> 8) & 0xff,
667 (address >> 0) & 0xff,
668 };
669
670 if (len > 256) {
671 printf_debug ("%s called for too long a write\n",
672 __FUNCTION__);
673 return 1;
674 }
675
676 memcpy(&cmd[4], bytes, len);
677
678 /* Send Byte-Program */
679 return spi_command(4 + len, 0, cmd, NULL);
680}
681
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000682int spi_disable_blockprotect(void)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000683{
684 uint8_t status;
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000685 int result;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000686
Peter Stugefa8c5502008-05-10 23:07:52 +0000687 status = spi_read_status_register();
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000688 /* If there is block protection in effect, unprotect it first. */
689 if ((status & 0x3c) != 0) {
690 printf_debug("Some block protection in effect, disabling\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000691 result = spi_write_status_enable();
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000692 if (result) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000693 printf_debug("spi_write_status_enable failed\n");
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000694 return result;
695 }
696 result = spi_write_status_register(status & ~0x3c);
697 if (result) {
698 printf_debug("spi_write_status_register failed\n");
699 return result;
700 }
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000701 }
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000702 return 0;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000703}
704
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000705int spi_nbyte_read(int address, uint8_t *bytes, int len)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000706{
Uwe Hermann394131e2008-10-18 21:14:13 +0000707 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
708 JEDEC_READ,
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000709 (address >> 16) & 0xff,
710 (address >> 8) & 0xff,
711 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000712 };
713
714 /* Send Read */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000715 return spi_command(sizeof(cmd), len, cmd, bytes);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000716}
717
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +0000718/*
719 * Read a complete flash chip.
720 * Each page is read separately in chunks with a maximum size of chunksize.
721 */
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000722int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +0000723{
724 int rc = 0;
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000725 int i, j, starthere, lenhere;
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +0000726 int page_size = flash->page_size;
727 int toread;
728
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000729 /* Warning: This loop has a very unusual condition and body.
730 * The loop needs to go through each page with at least one affected
731 * byte. The lowest page number is (start / page_size) since that
732 * division rounds down. The highest page number we want is the page
733 * where the last byte of the range lives. That last byte has the
734 * address (start + len - 1), thus the highest page number is
735 * (start + len - 1) / page_size. Since we want to include that last
736 * page as well, the loop condition uses <=.
737 */
738 for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
739 /* Byte position of the first byte in the range in this page. */
740 /* starthere is an offset to the base address of the chip. */
741 starthere = max(start, i * page_size);
742 /* Length of bytes in the range in this page. */
743 lenhere = min(start + len, (i + 1) * page_size) - starthere;
744 for (j = 0; j < lenhere; j += chunksize) {
745 toread = min(chunksize, lenhere - j);
746 rc = spi_nbyte_read(starthere + j, buf + starthere - start + j, toread);
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +0000747 if (rc)
748 break;
749 }
750 if (rc)
751 break;
752 }
753
754 return rc;
755}
756
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000757int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000758{
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000759 switch (spi_controller) {
760 case SPI_CONTROLLER_IT87XX:
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000761 return it8716f_spi_chip_read(flash, buf, start, len);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000762 case SPI_CONTROLLER_SB600:
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000763 return sb600_spi_read(flash, buf, start, len);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000764 case SPI_CONTROLLER_ICH7:
765 case SPI_CONTROLLER_ICH9:
766 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000767 return ich_spi_read(flash, buf, start, len);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000768 case SPI_CONTROLLER_WBSIO:
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +0000769 return wbsio_spi_read(flash, buf, start, len);
Paul Fox05dfbe62009-06-16 21:08:06 +0000770 case SPI_CONTROLLER_FT2232:
771 return ft2232_spi_read(flash, buf, start, len);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000772 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000773 printf_debug
774 ("%s called, but no SPI chipset/strapping detected\n",
775 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000776 }
777
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000778 return 1;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000779}
780
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000781/*
782 * Program chip using byte programming. (SLOW!)
783 * This is for chips which can only handle one byte writes
784 * and for chips where memory mapped programming is impossible
785 * (e.g. due to size constraints in IT87* for over 512 kB)
786 */
787int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
788{
789 int total_size = 1024 * flash->total_size;
790 int i;
791
792 spi_disable_blockprotect();
793 for (i = 0; i < total_size; i++) {
794 spi_write_enable();
795 spi_byte_program(i, buf[i]);
796 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000797 programmer_delay(10);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000798 }
799
800 return 0;
801}
802
803/*
804 * Program chip using page (256 bytes) programming.
805 * Some SPI masters can't do this, they use single byte programming instead.
806 */
Carl-Daniel Hailfinger8d497012009-05-09 02:34:18 +0000807int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000808{
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000809 switch (spi_controller) {
810 case SPI_CONTROLLER_IT87XX:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000811 return it8716f_spi_chip_write_256(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000812 case SPI_CONTROLLER_SB600:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000813 return sb600_spi_write_1(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000814 case SPI_CONTROLLER_ICH7:
815 case SPI_CONTROLLER_ICH9:
816 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000817 return ich_spi_write_256(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000818 case SPI_CONTROLLER_WBSIO:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000819 return wbsio_spi_write_1(flash, buf);
Paul Fox05dfbe62009-06-16 21:08:06 +0000820 case SPI_CONTROLLER_FT2232:
821 return ft2232_spi_write_256(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000822 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000823 printf_debug
824 ("%s called, but no SPI chipset/strapping detected\n",
825 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000826 }
827
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000828 return 1;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000829}
Peter Stugefd9217d2009-01-26 03:37:40 +0000830
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000831uint32_t spi_get_valid_read_addr(void)
832{
833 /* Need to return BBAR for ICH chipsets. */
834 return 0;
835}
836
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000837int spi_aai_write(struct flashchip *flash, uint8_t *buf)
838{
Peter Stugefd9217d2009-01-26 03:37:40 +0000839 uint32_t pos = 2, size = flash->total_size * 1024;
840 unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000841 int result;
842
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000843 switch (spi_controller) {
844 case SPI_CONTROLLER_WBSIO:
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000845 fprintf(stderr, "%s: impossible with Winbond SPI masters,"
846 " degrading to byte program\n", __func__);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000847 return spi_chip_write_1(flash, buf);
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000848 default:
849 break;
Peter Stugefd9217d2009-01-26 03:37:40 +0000850 }
Carl-Daniel Hailfinger3431bb72009-06-24 08:28:39 +0000851 if (flash->erase(flash)) {
852 fprintf(stderr, "ERASE FAILED!\n");
853 return -1;
854 }
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000855 result = spi_write_enable();
856 if (result)
857 return result;
Peter Stugefd9217d2009-01-26 03:37:40 +0000858 spi_command(6, 0, w, NULL);
859 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000860 programmer_delay(5); /* SST25VF040B Tbp is max 10us */
Peter Stugefd9217d2009-01-26 03:37:40 +0000861 while (pos < size) {
862 w[1] = buf[pos++];
863 w[2] = buf[pos++];
864 spi_command(3, 0, w, NULL);
865 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000866 programmer_delay(5); /* SST25VF040B Tbp is max 10us */
Peter Stugefd9217d2009-01-26 03:37:40 +0000867 }
868 spi_write_disable();
869 return 0;
870}