blob: e9319d74aedf36f4cafd21cb90860efc6904cc92 [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 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);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +000050 case SPI_CONTROLLER_DUMMY:
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000051 return dummy_spi_command(writecnt, readcnt, writearr, readarr);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000052 default:
Uwe Hermann394131e2008-10-18 21:14:13 +000053 printf_debug
54 ("%s called, but no SPI chipset/strapping detected\n",
55 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +000056 }
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +000057 return 1;
58}
59
Rudolf Marek48a85e42008-06-30 21:45:17 +000060static int spi_rdid(unsigned char *readarr, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000061{
Uwe Hermann394131e2008-10-18 21:14:13 +000062 const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000063 int ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000064 int i;
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000065
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000066 ret = spi_command(sizeof(cmd), bytes, cmd, readarr);
67 if (ret)
68 return ret;
Carl-Daniel Hailfingerbfe2e0c2009-05-14 12:59:36 +000069 printf_debug("RDID returned");
70 for (i = 0; i < bytes; i++)
71 printf_debug(" 0x%02x", readarr[i]);
72 printf_debug("\n");
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000073 return 0;
74}
75
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000076static int spi_rems(unsigned char *readarr)
77{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000078 unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
79 uint32_t readaddr;
80 int ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000081
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000082 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
83 if (ret == SPI_INVALID_ADDRESS) {
84 /* Find the lowest even address allowed for reads. */
85 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
86 cmd[1] = (readaddr >> 16) & 0xff,
87 cmd[2] = (readaddr >> 8) & 0xff,
88 cmd[3] = (readaddr >> 0) & 0xff,
89 ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
90 }
91 if (ret)
92 return ret;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +000093 printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
94 return 0;
95}
96
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +000097static int spi_res(unsigned char *readarr)
98{
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +000099 unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
100 uint32_t readaddr;
101 int ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000102
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000103 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
104 if (ret == SPI_INVALID_ADDRESS) {
105 /* Find the lowest even address allowed for reads. */
106 readaddr = (spi_get_valid_read_addr() + 1) & ~1;
107 cmd[1] = (readaddr >> 16) & 0xff,
108 cmd[2] = (readaddr >> 8) & 0xff,
109 cmd[3] = (readaddr >> 0) & 0xff,
110 ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
111 }
112 if (ret)
113 return ret;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000114 printf_debug("RES returned %02x.\n", readarr[0]);
115 return 0;
116}
117
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000118int spi_write_enable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000119{
Uwe Hermann394131e2008-10-18 21:14:13 +0000120 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000121 int result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000122
123 /* Send WREN (Write Enable) */
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000124 result = spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000125
126 if (result)
127 printf_debug("%s failed", __func__);
128 if (result == SPI_INVALID_OPCODE) {
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000129 switch (spi_controller) {
130 case SPI_CONTROLLER_ICH7:
131 case SPI_CONTROLLER_ICH9:
132 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000133 printf_debug(" due to SPI master limitation, ignoring"
134 " and hoping it will be run as PREOP\n");
135 return 0;
136 default:
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000137 break;
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000138 }
139 }
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000140 if (result)
141 printf_debug("\n");
142
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000143 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000144}
145
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000146int spi_write_disable(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000147{
Uwe Hermann394131e2008-10-18 21:14:13 +0000148 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000149
150 /* Send WRDI (Write Disable) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000151 return spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000152}
153
Rudolf Marek48a85e42008-06-30 21:45:17 +0000154static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000155{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000156 unsigned char readarr[4];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000157 uint32_t id1;
158 uint32_t id2;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000159
Rudolf Marek48a85e42008-06-30 21:45:17 +0000160 if (spi_rdid(readarr, bytes))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000161 return 0;
162
163 if (!oddparity(readarr[0]))
164 printf_debug("RDID byte 0 parity violation.\n");
165
166 /* Check if this is a continuation vendor ID */
167 if (readarr[0] == 0x7f) {
168 if (!oddparity(readarr[1]))
169 printf_debug("RDID byte 1 parity violation.\n");
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000170 id1 = (readarr[0] << 8) | readarr[1];
171 id2 = readarr[2];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000172 if (bytes > 3) {
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000173 id2 <<= 8;
174 id2 |= readarr[3];
Rudolf Marek48a85e42008-06-30 21:45:17 +0000175 }
Peter Stugeda4e5f32008-06-24 01:22:03 +0000176 } else {
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000177 id1 = readarr[0];
178 id2 = (readarr[1] << 8) | readarr[2];
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000179 }
180
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000181 printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __FUNCTION__, id1, id2);
Peter Stugeda4e5f32008-06-24 01:22:03 +0000182
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000183 if (id1 == flash->manufacture_id && id2 == flash->model_id) {
Peter Stugeda4e5f32008-06-24 01:22:03 +0000184 /* Print the status register to tell the
185 * user about possible write protection.
186 */
187 spi_prettyprint_status_register(flash);
188
189 return 1;
190 }
191
192 /* Test if this is a pure vendor match. */
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000193 if (id1 == flash->manufacture_id &&
Peter Stugeda4e5f32008-06-24 01:22:03 +0000194 GENERIC_DEVICE_ID == flash->model_id)
195 return 1;
196
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000197 return 0;
198}
199
Uwe Hermann394131e2008-10-18 21:14:13 +0000200int probe_spi_rdid(struct flashchip *flash)
201{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000202 return probe_spi_rdid_generic(flash, 3);
203}
204
205/* support 4 bytes flash ID */
Uwe Hermann394131e2008-10-18 21:14:13 +0000206int probe_spi_rdid4(struct flashchip *flash)
207{
Rudolf Marek48a85e42008-06-30 21:45:17 +0000208 /* only some SPI chipsets support 4 bytes commands */
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000209 switch (spi_controller) {
210 case SPI_CONTROLLER_ICH7:
211 case SPI_CONTROLLER_ICH9:
212 case SPI_CONTROLLER_VIA:
213 case SPI_CONTROLLER_SB600:
214 case SPI_CONTROLLER_WBSIO:
215 case SPI_CONTROLLER_DUMMY:
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000216 return probe_spi_rdid_generic(flash, 4);
217 default:
218 printf_debug("4b ID not supported on this SPI controller\n");
219 }
220
221 return 0;
Rudolf Marek48a85e42008-06-30 21:45:17 +0000222}
223
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000224int probe_spi_rems(struct flashchip *flash)
225{
226 unsigned char readarr[JEDEC_REMS_INSIZE];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000227 uint32_t id1, id2;
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000228
229 if (spi_rems(readarr))
230 return 0;
231
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000232 id1 = readarr[0];
233 id2 = readarr[1];
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000234
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000235 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000236
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000237 if (id1 == flash->manufacture_id && id2 == flash->model_id) {
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000238 /* Print the status register to tell the
239 * user about possible write protection.
240 */
241 spi_prettyprint_status_register(flash);
242
243 return 1;
244 }
245
246 /* Test if this is a pure vendor match. */
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000247 if (id1 == flash->manufacture_id &&
Carl-Daniel Hailfinger14e50ac2008-11-28 01:25:00 +0000248 GENERIC_DEVICE_ID == flash->model_id)
249 return 1;
250
251 return 0;
252}
253
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000254int probe_spi_res(struct flashchip *flash)
255{
256 unsigned char readarr[3];
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000257 uint32_t id2;
Peter Stugeda4e5f32008-06-24 01:22:03 +0000258
Carl-Daniel Hailfinger92a54ca2008-11-27 22:48:48 +0000259 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
260 * In that case, RES is pointless.
261 */
262 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
263 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
Peter Stugeda4e5f32008-06-24 01:22:03 +0000264 return 0;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000265
Peter Stugeda4e5f32008-06-24 01:22:03 +0000266 if (spi_res(readarr))
267 return 0;
268
Carl-Daniel Hailfinger2ad267d2009-05-27 11:40:08 +0000269 id2 = readarr[0];
270 printf_debug("%s: id 0x%x\n", __FUNCTION__, id2);
271 if (id2 != flash->model_id)
Peter Stugeda4e5f32008-06-24 01:22:03 +0000272 return 0;
273
274 /* Print the status register to tell the
275 * user about possible write protection.
276 */
277 spi_prettyprint_status_register(flash);
278 return 1;
Carl-Daniel Hailfinger42c54972008-05-15 03:19:49 +0000279}
280
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000281uint8_t spi_read_status_register(void)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000282{
Uwe Hermann394131e2008-10-18 21:14:13 +0000283 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
Peter Stugebf196e92009-01-26 03:08:45 +0000284 unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000285 int ret;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000286
287 /* Read Status Register */
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000288 if (spi_controller == SPI_CONTROLLER_SB600) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000289 /* SB600 uses a different way to read status register. */
290 return sb600_read_status_register();
291 } else {
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000292 ret = spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
293 if (ret)
294 printf_debug("RDSR failed!\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000295 }
296
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000297 return readarr[0];
298}
299
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000300/* Prettyprint the status register. Common definitions. */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000301void spi_prettyprint_status_register_common(uint8_t status)
302{
303 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000304 "%sset\n", (status & (1 << 5)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000305 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000306 "%sset\n", (status & (1 << 4)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000307 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000308 "%sset\n", (status & (1 << 3)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000309 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000310 "%sset\n", (status & (1 << 2)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000311 printf_debug("Chip status register: Write Enable Latch (WEL) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000312 "%sset\n", (status & (1 << 1)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000313 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000314 "%sset\n", (status & (1 << 0)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000315}
316
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000317/* Prettyprint the status register. Works for
318 * ST M25P series
319 * MX MX25L series
320 */
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000321void spi_prettyprint_status_register_st_m25p(uint8_t status)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000322{
323 printf_debug("Chip status register: Status Register Write Disable "
Uwe Hermann394131e2008-10-18 21:14:13 +0000324 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000325 printf_debug("Chip status register: Bit 6 is "
Uwe Hermann394131e2008-10-18 21:14:13 +0000326 "%sset\n", (status & (1 << 6)) ? "" : "not ");
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000327 spi_prettyprint_status_register_common(status);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000328}
329
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000330void spi_prettyprint_status_register_sst25(uint8_t status)
331{
332 printf_debug("Chip status register: Block Protect Write Disable "
333 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
334 printf_debug("Chip status register: Auto Address Increment Programming "
335 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
336 spi_prettyprint_status_register_common(status);
337}
338
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000339/* Prettyprint the status register. Works for
340 * SST 25VF016
341 */
342void spi_prettyprint_status_register_sst25vf016(uint8_t status)
343{
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000344 const char *bpt[] = {
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000345 "none",
346 "1F0000H-1FFFFFH",
347 "1E0000H-1FFFFFH",
348 "1C0000H-1FFFFFH",
349 "180000H-1FFFFFH",
350 "100000H-1FFFFFH",
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000351 "all", "all"
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000352 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000353 spi_prettyprint_status_register_sst25(status);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000354 printf_debug("Resulting block protection : %s\n",
Uwe Hermann394131e2008-10-18 21:14:13 +0000355 bpt[(status & 0x1c) >> 2]);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000356}
357
Peter Stuge5fecee42009-01-26 03:23:50 +0000358void spi_prettyprint_status_register_sst25vf040b(uint8_t status)
359{
360 const char *bpt[] = {
361 "none",
362 "0x70000-0x7ffff",
363 "0x60000-0x7ffff",
364 "0x40000-0x7ffff",
365 "all blocks", "all blocks", "all blocks", "all blocks"
366 };
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000367 spi_prettyprint_status_register_sst25(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000368 printf_debug("Resulting block protection : %s\n",
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000369 bpt[(status & 0x1c) >> 2]);
Peter Stuge5fecee42009-01-26 03:23:50 +0000370}
371
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000372void spi_prettyprint_status_register(struct flashchip *flash)
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000373{
374 uint8_t status;
375
Peter Stugefa8c5502008-05-10 23:07:52 +0000376 status = spi_read_status_register();
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000377 printf_debug("Chip status register is %02x\n", status);
378 switch (flash->manufacture_id) {
379 case ST_ID:
Carl-Daniel Hailfingerf43e6422008-05-15 22:32:08 +0000380 if (((flash->model_id & 0xff00) == 0x2000) ||
381 ((flash->model_id & 0xff00) == 0x2500))
382 spi_prettyprint_status_register_st_m25p(status);
383 break;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000384 case MX_ID:
385 if ((flash->model_id & 0xff00) == 0x2000)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000386 spi_prettyprint_status_register_st_m25p(status);
387 break;
388 case SST_ID:
Peter Stuge5fecee42009-01-26 03:23:50 +0000389 switch (flash->model_id) {
390 case 0x2541:
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000391 spi_prettyprint_status_register_sst25vf016(status);
Peter Stuge5fecee42009-01-26 03:23:50 +0000392 break;
393 case 0x8d:
394 case 0x258d:
395 spi_prettyprint_status_register_sst25vf040b(status);
396 break;
Carl-Daniel Hailfinger5100a8a2009-05-13 22:51:27 +0000397 default:
Carl-Daniel Hailfinger1bfd6c92009-05-06 13:59:44 +0000398 spi_prettyprint_status_register_sst25(status);
399 break;
Peter Stuge5fecee42009-01-26 03:23:50 +0000400 }
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000401 break;
402 }
403}
Uwe Hermann394131e2008-10-18 21:14:13 +0000404
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000405int spi_chip_erase_60(struct flashchip *flash)
406{
407 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000408 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000409
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000410 result = spi_disable_blockprotect();
411 if (result) {
412 printf_debug("spi_disable_blockprotect failed\n");
413 return result;
414 }
415 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000416 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000417 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000418 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000419 result = spi_command(sizeof(cmd), 0, cmd, NULL);
420 if (result) {
421 printf_debug("spi_chip_erase_60 failed sending erase\n");
422 return result;
423 }
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000424 /* Wait until the Write-In-Progress bit is cleared.
425 * This usually takes 1-85 s, so wait in 1 s steps.
426 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000427 /* FIXME: We assume spi_read_status_register will never fail. */
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000428 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000429 programmer_delay(1000 * 1000);
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000430 return 0;
431}
432
Peter Stugefa8c5502008-05-10 23:07:52 +0000433int spi_chip_erase_c7(struct flashchip *flash)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000434{
Uwe Hermann394131e2008-10-18 21:14:13 +0000435 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000436 int result;
Uwe Hermann394131e2008-10-18 21:14:13 +0000437
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000438 result = spi_disable_blockprotect();
439 if (result) {
440 printf_debug("spi_disable_blockprotect failed\n");
441 return result;
442 }
443 result = spi_write_enable();
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000444 if (result)
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000445 return result;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000446 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000447 result = spi_command(sizeof(cmd), 0, cmd, NULL);
448 if (result) {
449 printf_debug("spi_chip_erase_60 failed sending erase\n");
450 return result;
451 }
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000452 /* Wait until the Write-In-Progress bit is cleared.
453 * This usually takes 1-85 s, so wait in 1 s steps.
454 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000455 /* FIXME: We assume spi_read_status_register will never fail. */
Peter Stugefa8c5502008-05-10 23:07:52 +0000456 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000457 programmer_delay(1000 * 1000);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000458 return 0;
459}
460
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000461int spi_chip_erase_60_c7(struct flashchip *flash)
462{
463 int result;
464 result = spi_chip_erase_60(flash);
465 if (result) {
466 printf_debug("spi_chip_erase_60 failed, trying c7\n");
467 result = spi_chip_erase_c7(flash);
468 }
469 return result;
470}
471
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000472int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
473{
474 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000475 int result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000476
477 cmd[1] = (addr & 0x00ff0000) >> 16;
478 cmd[2] = (addr & 0x0000ff00) >> 8;
479 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000480 result = spi_write_enable();
481 if (result)
482 return result;
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000483 /* Send BE (Block Erase) */
484 spi_command(sizeof(cmd), 0, cmd, NULL);
485 /* Wait until the Write-In-Progress bit is cleared.
486 * This usually takes 100-4000 ms, so wait in 100 ms steps.
487 */
488 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000489 programmer_delay(100 * 1000);
Carl-Daniel Hailfinger6afb6132008-11-03 00:02:11 +0000490 return 0;
491}
492
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000493/* Block size is usually
494 * 64k for Macronix
495 * 32k for SST
496 * 4-32k non-uniform for EON
497 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000498int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000499{
Uwe Hermann394131e2008-10-18 21:14:13 +0000500 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000501 int result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000502
503 cmd[1] = (addr & 0x00ff0000) >> 16;
504 cmd[2] = (addr & 0x0000ff00) >> 8;
505 cmd[3] = (addr & 0x000000ff);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000506 result = spi_write_enable();
507 if (result)
508 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000509 /* Send BE (Block Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000510 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000511 /* Wait until the Write-In-Progress bit is cleared.
512 * This usually takes 100-4000 ms, so wait in 100 ms steps.
513 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000514 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000515 programmer_delay(100 * 1000);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000516 return 0;
517}
518
Stefan Reinauer424ed222008-10-29 22:13:20 +0000519int spi_chip_erase_d8(struct flashchip *flash)
520{
521 int i, rc = 0;
522 int total_size = flash->total_size * 1024;
523 int erase_size = 64 * 1024;
524
525 spi_disable_blockprotect();
526
527 printf("Erasing chip: \n");
528
529 for (i = 0; i < total_size / erase_size; i++) {
530 rc = spi_block_erase_d8(flash, i * erase_size);
531 if (rc) {
532 printf("Error erasing block at 0x%x\n", i);
533 break;
534 }
535 }
536
537 printf("\n");
538
539 return rc;
540}
541
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000542/* Sector size is usually 4k, though Macronix eliteflash has 64k */
Peter Stugefa8c5502008-05-10 23:07:52 +0000543int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000544{
Uwe Hermann394131e2008-10-18 21:14:13 +0000545 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE };
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000546 int result;
547
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000548 cmd[1] = (addr & 0x00ff0000) >> 16;
549 cmd[2] = (addr & 0x0000ff00) >> 8;
550 cmd[3] = (addr & 0x000000ff);
551
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000552 result = spi_write_enable();
553 if (result)
554 return result;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000555 /* Send SE (Sector Erase) */
Peter Stugef83221b2008-07-07 06:38:51 +0000556 spi_command(sizeof(cmd), 0, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000557 /* Wait until the Write-In-Progress bit is cleared.
558 * This usually takes 15-800 ms, so wait in 10 ms steps.
559 */
Peter Stugefa8c5502008-05-10 23:07:52 +0000560 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000561 programmer_delay(10 * 1000);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000562 return 0;
563}
564
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000565int spi_write_status_enable(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000566{
567 const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000568 int result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000569
570 /* Send EWSR (Enable Write Status Register). */
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000571 result = spi_command(sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
572
573 if (result)
574 printf_debug("%s failed", __func__);
575 if (result == SPI_INVALID_OPCODE) {
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000576 switch (spi_controller) {
577 case SPI_CONTROLLER_ICH7:
578 case SPI_CONTROLLER_ICH9:
579 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger1e637842009-05-15 00:56:22 +0000580 printf_debug(" due to SPI master limitation, ignoring"
581 " and hoping it will be run as PREOP\n");
582 return 0;
583 default:
584 break;
585 }
586 }
587 if (result)
588 printf_debug("\n");
589
590 return result;
Jason Wanga3f04be2008-11-28 21:36:51 +0000591}
592
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000593/*
594 * This is according the SST25VF016 datasheet, who knows it is more
595 * generic that this...
596 */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000597int spi_write_status_register(int status)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000598{
Uwe Hermann394131e2008-10-18 21:14:13 +0000599 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
600 { JEDEC_WRSR, (unsigned char)status };
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000601
602 /* Send WRSR (Write Status Register) */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000603 return spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000604}
605
606void spi_byte_program(int address, uint8_t byte)
607{
Uwe Hermann394131e2008-10-18 21:14:13 +0000608 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
609 JEDEC_BYTE_PROGRAM,
610 (address >> 16) & 0xff,
611 (address >> 8) & 0xff,
612 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000613 byte
614 };
615
616 /* Send Byte-Program */
Peter Stugef83221b2008-07-07 06:38:51 +0000617 spi_command(sizeof(cmd), 0, cmd, NULL);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000618}
619
Paul Foxeb3acef2009-06-12 08:10:33 +0000620int spi_nbyte_program(int address, uint8_t *bytes, int len)
621{
622 unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + 256] = {
623 JEDEC_BYTE_PROGRAM,
624 (address >> 16) & 0xff,
625 (address >> 8) & 0xff,
626 (address >> 0) & 0xff,
627 };
628
629 if (len > 256) {
630 printf_debug ("%s called for too long a write\n",
631 __FUNCTION__);
632 return 1;
633 }
634
635 memcpy(&cmd[4], bytes, len);
636
637 /* Send Byte-Program */
638 return spi_command(4 + len, 0, cmd, NULL);
639}
640
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000641int spi_disable_blockprotect(void)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000642{
643 uint8_t status;
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000644 int result;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000645
Peter Stugefa8c5502008-05-10 23:07:52 +0000646 status = spi_read_status_register();
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000647 /* If there is block protection in effect, unprotect it first. */
648 if ((status & 0x3c) != 0) {
649 printf_debug("Some block protection in effect, disabling\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000650 result = spi_write_status_enable();
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000651 if (result) {
Jason Wanga3f04be2008-11-28 21:36:51 +0000652 printf_debug("spi_write_status_enable failed\n");
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000653 return result;
654 }
655 result = spi_write_status_register(status & ~0x3c);
656 if (result) {
657 printf_debug("spi_write_status_register failed\n");
658 return result;
659 }
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000660 }
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000661 return 0;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000662}
663
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000664int spi_nbyte_read(int address, uint8_t *bytes, int len)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000665{
Uwe Hermann394131e2008-10-18 21:14:13 +0000666 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
667 JEDEC_READ,
Carl-Daniel Hailfingerd3568ad2008-01-22 14:37:31 +0000668 (address >> 16) & 0xff,
669 (address >> 8) & 0xff,
670 (address >> 0) & 0xff,
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000671 };
672
673 /* Send Read */
Carl-Daniel Hailfinger598ec582008-11-18 00:41:02 +0000674 return spi_command(sizeof(cmd), len, cmd, bytes);
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000675}
676
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +0000677/*
678 * Read a complete flash chip.
679 * Each page is read separately in chunks with a maximum size of chunksize.
680 */
681int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int chunksize)
682{
683 int rc = 0;
684 int i, j;
685 int total_size = flash->total_size * 1024;
686 int page_size = flash->page_size;
687 int toread;
688
689 for (j = 0; j < total_size / page_size; j++) {
690 for (i = 0; i < page_size; i += chunksize) {
691 toread = min(chunksize, page_size - i);
692 rc = spi_nbyte_read(j * page_size + i,
693 buf + j * page_size + i, toread);
694 if (rc)
695 break;
696 }
697 if (rc)
698 break;
699 }
700
701 return rc;
702}
703
Peter Stugefa8c5502008-05-10 23:07:52 +0000704int spi_chip_read(struct flashchip *flash, uint8_t *buf)
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000705{
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000706 switch (spi_controller) {
707 case SPI_CONTROLLER_IT87XX:
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000708 return it8716f_spi_chip_read(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000709 case SPI_CONTROLLER_SB600:
Jason Wanga3f04be2008-11-28 21:36:51 +0000710 return sb600_spi_read(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000711 case SPI_CONTROLLER_ICH7:
712 case SPI_CONTROLLER_ICH9:
713 case SPI_CONTROLLER_VIA:
Rudolf Marek3fdbccf2008-06-30 21:38:30 +0000714 return ich_spi_read(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000715 case SPI_CONTROLLER_WBSIO:
Peter Stugebf196e92009-01-26 03:08:45 +0000716 return wbsio_spi_read(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000717 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000718 printf_debug
719 ("%s called, but no SPI chipset/strapping detected\n",
720 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000721 }
722
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000723 return 1;
Ronald Hoogenboom7ff530b2008-01-19 00:04:46 +0000724}
725
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000726/*
727 * Program chip using byte programming. (SLOW!)
728 * This is for chips which can only handle one byte writes
729 * and for chips where memory mapped programming is impossible
730 * (e.g. due to size constraints in IT87* for over 512 kB)
731 */
732int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
733{
734 int total_size = 1024 * flash->total_size;
735 int i;
736
737 spi_disable_blockprotect();
738 for (i = 0; i < total_size; i++) {
739 spi_write_enable();
740 spi_byte_program(i, buf[i]);
741 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000742 programmer_delay(10);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000743 }
744
745 return 0;
746}
747
748/*
749 * Program chip using page (256 bytes) programming.
750 * Some SPI masters can't do this, they use single byte programming instead.
751 */
Carl-Daniel Hailfinger8d497012009-05-09 02:34:18 +0000752int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000753{
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000754 switch (spi_controller) {
755 case SPI_CONTROLLER_IT87XX:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000756 return it8716f_spi_chip_write_256(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000757 case SPI_CONTROLLER_SB600:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000758 return sb600_spi_write_1(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000759 case SPI_CONTROLLER_ICH7:
760 case SPI_CONTROLLER_ICH9:
761 case SPI_CONTROLLER_VIA:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000762 return ich_spi_write_256(flash, buf);
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000763 case SPI_CONTROLLER_WBSIO:
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000764 return wbsio_spi_write_1(flash, buf);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000765 default:
Uwe Hermann394131e2008-10-18 21:14:13 +0000766 printf_debug
767 ("%s called, but no SPI chipset/strapping detected\n",
768 __FUNCTION__);
Stefan Reinauer2cb94e12008-06-30 23:45:22 +0000769 }
770
Carl-Daniel Hailfingerbfe5b4a2008-05-13 23:03:12 +0000771 return 1;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000772}
Peter Stugefd9217d2009-01-26 03:37:40 +0000773
Carl-Daniel Hailfinger3e9dbea2009-05-13 11:40:08 +0000774uint32_t spi_get_valid_read_addr(void)
775{
776 /* Need to return BBAR for ICH chipsets. */
777 return 0;
778}
779
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000780int spi_aai_write(struct flashchip *flash, uint8_t *buf)
781{
Peter Stugefd9217d2009-01-26 03:37:40 +0000782 uint32_t pos = 2, size = flash->total_size * 1024;
783 unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]};
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000784 int result;
785
Carl-Daniel Hailfinger1dfe0ff2009-05-31 17:57:34 +0000786 switch (spi_controller) {
787 case SPI_CONTROLLER_WBSIO:
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000788 fprintf(stderr, "%s: impossible with Winbond SPI masters,"
789 " degrading to byte program\n", __func__);
Carl-Daniel Hailfinger96930c32009-05-09 02:30:21 +0000790 return spi_chip_write_1(flash, buf);
Uwe Hermann7b2969b2009-04-15 10:52:49 +0000791 default:
792 break;
Peter Stugefd9217d2009-01-26 03:37:40 +0000793 }
794 flash->erase(flash);
Carl-Daniel Hailfinger03adbe12009-05-09 02:09:45 +0000795 result = spi_write_enable();
796 if (result)
797 return result;
Peter Stugefd9217d2009-01-26 03:37:40 +0000798 spi_command(6, 0, w, NULL);
799 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000800 programmer_delay(5); /* SST25VF040B Tbp is max 10us */
Peter Stugefd9217d2009-01-26 03:37:40 +0000801 while (pos < size) {
802 w[1] = buf[pos++];
803 w[2] = buf[pos++];
804 spi_command(3, 0, w, NULL);
805 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000806 programmer_delay(5); /* SST25VF040B Tbp is max 10us */
Peter Stugefd9217d2009-01-26 03:37:40 +0000807 }
808 spi_write_disable();
809 return 0;
810}