blob: 8812eff12329386aa0f854e23486a379cbb1cb60 [file] [log] [blame]
stepand4b13752007-10-15 21:45:29 +00001/*
2 * This file is part of the flashrom project.
3 *
hailfingerb8f7e882008-01-19 00:04:46 +00004 * Copyright (C) 2007, 2008 Carl-Daniel Hailfinger
stepandbd3af12008-06-27 16:28:34 +00005 * Copyright (C) 2008 coresystems GmbH
stepand4b13752007-10-15 21:45:29 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * Contains the generic SPI framework
23 */
24
25#include <stdio.h>
26#include <pci/pci.h>
27#include <stdint.h>
28#include <string.h>
29#include "flash.h"
hailfinger78031562008-05-13 14:58:23 +000030#include "spi.h"
stepand4b13752007-10-15 21:45:29 +000031
hailfingerb8f7e882008-01-19 00:04:46 +000032void spi_prettyprint_status_register(struct flashchip *flash);
stepand4b13752007-10-15 21:45:29 +000033
uwefa98ca12008-10-18 21:14:13 +000034int spi_command(unsigned int writecnt, unsigned int readcnt,
35 const unsigned char *writearr, unsigned char *readarr)
hailfinger35cc8162007-10-16 21:09:06 +000036{
stepan3bdf6182008-06-30 23:45:22 +000037 switch (flashbus) {
38 case BUS_TYPE_IT87XX_SPI:
uwefa98ca12008-10-18 21:14:13 +000039 return it8716f_spi_command(writecnt, readcnt, writearr,
40 readarr);
stepan3bdf6182008-06-30 23:45:22 +000041 case BUS_TYPE_ICH7_SPI:
42 case BUS_TYPE_ICH9_SPI:
43 case BUS_TYPE_VIA_SPI:
uwefa98ca12008-10-18 21:14:13 +000044 return ich_spi_command(writecnt, readcnt, writearr, readarr);
stepan3bdf6182008-06-30 23:45:22 +000045 default:
uwefa98ca12008-10-18 21:14:13 +000046 printf_debug
47 ("%s called, but no SPI chipset/strapping detected\n",
48 __FUNCTION__);
stepan3bdf6182008-06-30 23:45:22 +000049 }
hailfinger35cc8162007-10-16 21:09:06 +000050 return 1;
51}
52
ruikdbe18ee2008-06-30 21:45:17 +000053static int spi_rdid(unsigned char *readarr, int bytes)
stepand4b13752007-10-15 21:45:29 +000054{
uwefa98ca12008-10-18 21:14:13 +000055 const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
stepand4b13752007-10-15 21:45:29 +000056
stuge494b4eb2008-07-07 06:38:51 +000057 if (spi_command(sizeof(cmd), bytes, cmd, readarr))
stepand4b13752007-10-15 21:45:29 +000058 return 1;
uwefa98ca12008-10-18 21:14:13 +000059 printf_debug("RDID returned %02x %02x %02x.\n", readarr[0], readarr[1],
60 readarr[2]);
stepand4b13752007-10-15 21:45:29 +000061 return 0;
62}
63
hailfinger3dd0c3e2008-11-28 01:25:00 +000064static int spi_rems(unsigned char *readarr)
65{
66 const unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
67
68 if (spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr))
69 return 1;
70 printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
71 return 0;
72}
73
hailfinger82893122008-05-15 03:19:49 +000074static int spi_res(unsigned char *readarr)
75{
uwefa98ca12008-10-18 21:14:13 +000076 const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
hailfinger82893122008-05-15 03:19:49 +000077
stuge494b4eb2008-07-07 06:38:51 +000078 if (spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr))
hailfinger82893122008-05-15 03:19:49 +000079 return 1;
80 printf_debug("RES returned %02x.\n", readarr[0]);
81 return 0;
82}
83
hailfingerc1b2e912008-11-18 00:41:02 +000084int spi_write_enable()
hailfingerf71c0ac2007-10-18 00:24:07 +000085{
uwefa98ca12008-10-18 21:14:13 +000086 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
hailfingerf71c0ac2007-10-18 00:24:07 +000087
88 /* Send WREN (Write Enable) */
hailfingerc1b2e912008-11-18 00:41:02 +000089 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerf71c0ac2007-10-18 00:24:07 +000090}
91
hailfingerc1b2e912008-11-18 00:41:02 +000092int spi_write_disable()
hailfingerf71c0ac2007-10-18 00:24:07 +000093{
uwefa98ca12008-10-18 21:14:13 +000094 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
hailfingerf71c0ac2007-10-18 00:24:07 +000095
96 /* Send WRDI (Write Disable) */
hailfingerc1b2e912008-11-18 00:41:02 +000097 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerf71c0ac2007-10-18 00:24:07 +000098}
99
ruikdbe18ee2008-06-30 21:45:17 +0000100static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
stepand4b13752007-10-15 21:45:29 +0000101{
ruikdbe18ee2008-06-30 21:45:17 +0000102 unsigned char readarr[4];
hailfinger492e3172008-02-06 22:07:58 +0000103 uint32_t manuf_id;
104 uint32_t model_id;
hailfingerf1961cb2007-12-29 10:15:58 +0000105
ruikdbe18ee2008-06-30 21:45:17 +0000106 if (spi_rdid(readarr, bytes))
stuge7be66832008-06-24 01:22:03 +0000107 return 0;
108
109 if (!oddparity(readarr[0]))
110 printf_debug("RDID byte 0 parity violation.\n");
111
112 /* Check if this is a continuation vendor ID */
113 if (readarr[0] == 0x7f) {
114 if (!oddparity(readarr[1]))
115 printf_debug("RDID byte 1 parity violation.\n");
116 manuf_id = (readarr[0] << 8) | readarr[1];
117 model_id = readarr[2];
ruikdbe18ee2008-06-30 21:45:17 +0000118 if (bytes > 3) {
119 model_id <<= 8;
120 model_id |= readarr[3];
121 }
stuge7be66832008-06-24 01:22:03 +0000122 } else {
123 manuf_id = readarr[0];
124 model_id = (readarr[1] << 8) | readarr[2];
stepand4b13752007-10-15 21:45:29 +0000125 }
126
uwefa98ca12008-10-18 21:14:13 +0000127 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id,
128 model_id);
stuge7be66832008-06-24 01:22:03 +0000129
uwefa98ca12008-10-18 21:14:13 +0000130 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
stuge7be66832008-06-24 01:22:03 +0000131 /* Print the status register to tell the
132 * user about possible write protection.
133 */
134 spi_prettyprint_status_register(flash);
135
136 return 1;
137 }
138
139 /* Test if this is a pure vendor match. */
140 if (manuf_id == flash->manufacture_id &&
141 GENERIC_DEVICE_ID == flash->model_id)
142 return 1;
143
stepand4b13752007-10-15 21:45:29 +0000144 return 0;
145}
146
uwefa98ca12008-10-18 21:14:13 +0000147int probe_spi_rdid(struct flashchip *flash)
148{
ruikdbe18ee2008-06-30 21:45:17 +0000149 return probe_spi_rdid_generic(flash, 3);
150}
151
152/* support 4 bytes flash ID */
uwefa98ca12008-10-18 21:14:13 +0000153int probe_spi_rdid4(struct flashchip *flash)
154{
ruikdbe18ee2008-06-30 21:45:17 +0000155 /* only some SPI chipsets support 4 bytes commands */
stepan3bdf6182008-06-30 23:45:22 +0000156 switch (flashbus) {
157 case BUS_TYPE_ICH7_SPI:
158 case BUS_TYPE_ICH9_SPI:
159 case BUS_TYPE_VIA_SPI:
160 return probe_spi_rdid_generic(flash, 4);
161 default:
162 printf_debug("4b ID not supported on this SPI controller\n");
163 }
164
165 return 0;
ruikdbe18ee2008-06-30 21:45:17 +0000166}
167
hailfinger3dd0c3e2008-11-28 01:25:00 +0000168int probe_spi_rems(struct flashchip *flash)
169{
170 unsigned char readarr[JEDEC_REMS_INSIZE];
171 uint32_t manuf_id, model_id;
172
173 if (spi_rems(readarr))
174 return 0;
175
176 manuf_id = readarr[0];
177 model_id = readarr[1];
178
179 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id,
180 model_id);
181
182 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
183 /* Print the status register to tell the
184 * user about possible write protection.
185 */
186 spi_prettyprint_status_register(flash);
187
188 return 1;
189 }
190
191 /* Test if this is a pure vendor match. */
192 if (manuf_id == flash->manufacture_id &&
193 GENERIC_DEVICE_ID == flash->model_id)
194 return 1;
195
196 return 0;
197}
198
hailfinger82893122008-05-15 03:19:49 +0000199int probe_spi_res(struct flashchip *flash)
200{
201 unsigned char readarr[3];
202 uint32_t model_id;
stuge7be66832008-06-24 01:22:03 +0000203
hailfinger915cc852008-11-27 22:48:48 +0000204 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
205 * In that case, RES is pointless.
206 */
207 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
208 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
stuge7be66832008-06-24 01:22:03 +0000209 return 0;
hailfinger82893122008-05-15 03:19:49 +0000210
stuge7be66832008-06-24 01:22:03 +0000211 if (spi_res(readarr))
212 return 0;
213
214 model_id = readarr[0];
215 printf_debug("%s: id 0x%x\n", __FUNCTION__, model_id);
216 if (model_id != flash->model_id)
217 return 0;
218
219 /* Print the status register to tell the
220 * user about possible write protection.
221 */
222 spi_prettyprint_status_register(flash);
223 return 1;
hailfinger82893122008-05-15 03:19:49 +0000224}
225
stuge2bb6ab32008-05-10 23:07:52 +0000226uint8_t spi_read_status_register()
hailfingerf71c0ac2007-10-18 00:24:07 +0000227{
uwefa98ca12008-10-18 21:14:13 +0000228 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
stuge494b4eb2008-07-07 06:38:51 +0000229 unsigned char readarr[JEDEC_RDSR_INSIZE];
hailfingerf71c0ac2007-10-18 00:24:07 +0000230
231 /* Read Status Register */
stuge494b4eb2008-07-07 06:38:51 +0000232 spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
hailfingerf71c0ac2007-10-18 00:24:07 +0000233 return readarr[0];
234}
235
hailfingerb8f7e882008-01-19 00:04:46 +0000236/* Prettyprint the status register. Common definitions.
237 */
238void spi_prettyprint_status_register_common(uint8_t status)
239{
240 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
uwefa98ca12008-10-18 21:14:13 +0000241 "%sset\n", (status & (1 << 5)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000242 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
uwefa98ca12008-10-18 21:14:13 +0000243 "%sset\n", (status & (1 << 4)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000244 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
uwefa98ca12008-10-18 21:14:13 +0000245 "%sset\n", (status & (1 << 3)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000246 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
uwefa98ca12008-10-18 21:14:13 +0000247 "%sset\n", (status & (1 << 2)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000248 printf_debug("Chip status register: Write Enable Latch (WEL) is "
uwefa98ca12008-10-18 21:14:13 +0000249 "%sset\n", (status & (1 << 1)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000250 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
uwefa98ca12008-10-18 21:14:13 +0000251 "%sset\n", (status & (1 << 0)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000252}
253
hailfingerf1961cb2007-12-29 10:15:58 +0000254/* Prettyprint the status register. Works for
255 * ST M25P series
256 * MX MX25L series
257 */
hailfingerb8f7e882008-01-19 00:04:46 +0000258void spi_prettyprint_status_register_st_m25p(uint8_t status)
hailfingerf1961cb2007-12-29 10:15:58 +0000259{
260 printf_debug("Chip status register: Status Register Write Disable "
uwefa98ca12008-10-18 21:14:13 +0000261 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
hailfingerf1961cb2007-12-29 10:15:58 +0000262 printf_debug("Chip status register: Bit 6 is "
uwefa98ca12008-10-18 21:14:13 +0000263 "%sset\n", (status & (1 << 6)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000264 spi_prettyprint_status_register_common(status);
hailfingerf1961cb2007-12-29 10:15:58 +0000265}
266
hailfingerb8f7e882008-01-19 00:04:46 +0000267/* Prettyprint the status register. Works for
268 * SST 25VF016
269 */
270void spi_prettyprint_status_register_sst25vf016(uint8_t status)
271{
hailfinger9cd4cf12008-01-22 14:37:31 +0000272 const char *bpt[] = {
hailfingerb8f7e882008-01-19 00:04:46 +0000273 "none",
274 "1F0000H-1FFFFFH",
275 "1E0000H-1FFFFFH",
276 "1C0000H-1FFFFFH",
277 "180000H-1FFFFFH",
278 "100000H-1FFFFFH",
hailfinger9cd4cf12008-01-22 14:37:31 +0000279 "all", "all"
hailfingerb8f7e882008-01-19 00:04:46 +0000280 };
281 printf_debug("Chip status register: Block Protect Write Disable "
uwefa98ca12008-10-18 21:14:13 +0000282 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000283 printf_debug("Chip status register: Auto Address Increment Programming "
uwefa98ca12008-10-18 21:14:13 +0000284 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000285 spi_prettyprint_status_register_common(status);
286 printf_debug("Resulting block protection : %s\n",
uwefa98ca12008-10-18 21:14:13 +0000287 bpt[(status & 0x1c) >> 2]);
hailfingerb8f7e882008-01-19 00:04:46 +0000288}
289
290void spi_prettyprint_status_register(struct flashchip *flash)
hailfingerf1961cb2007-12-29 10:15:58 +0000291{
292 uint8_t status;
293
stuge2bb6ab32008-05-10 23:07:52 +0000294 status = spi_read_status_register();
hailfingerf1961cb2007-12-29 10:15:58 +0000295 printf_debug("Chip status register is %02x\n", status);
296 switch (flash->manufacture_id) {
297 case ST_ID:
hailfinger8b869132008-05-15 22:32:08 +0000298 if (((flash->model_id & 0xff00) == 0x2000) ||
299 ((flash->model_id & 0xff00) == 0x2500))
300 spi_prettyprint_status_register_st_m25p(status);
301 break;
hailfingerf1961cb2007-12-29 10:15:58 +0000302 case MX_ID:
303 if ((flash->model_id & 0xff00) == 0x2000)
hailfingerb8f7e882008-01-19 00:04:46 +0000304 spi_prettyprint_status_register_st_m25p(status);
305 break;
306 case SST_ID:
307 if (flash->model_id == SST_25VF016B)
308 spi_prettyprint_status_register_sst25vf016(status);
hailfingerf1961cb2007-12-29 10:15:58 +0000309 break;
310 }
311}
uwefa98ca12008-10-18 21:14:13 +0000312
hailfingerffcf81a2008-11-03 00:02:11 +0000313int spi_chip_erase_60(struct flashchip *flash)
314{
315 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
hailfingerc1b2e912008-11-18 00:41:02 +0000316 int result;
hailfingerffcf81a2008-11-03 00:02:11 +0000317
hailfingerc1b2e912008-11-18 00:41:02 +0000318 result = spi_disable_blockprotect();
319 if (result) {
320 printf_debug("spi_disable_blockprotect failed\n");
321 return result;
322 }
323 result = spi_write_enable();
324 if (result) {
325 printf_debug("spi_write_enable failed\n");
326 return result;
327 }
hailfingerffcf81a2008-11-03 00:02:11 +0000328 /* Send CE (Chip Erase) */
hailfingerc1b2e912008-11-18 00:41:02 +0000329 result = spi_command(sizeof(cmd), 0, cmd, NULL);
330 if (result) {
331 printf_debug("spi_chip_erase_60 failed sending erase\n");
332 return result;
333 }
hailfingerffcf81a2008-11-03 00:02:11 +0000334 /* Wait until the Write-In-Progress bit is cleared.
335 * This usually takes 1-85 s, so wait in 1 s steps.
336 */
hailfingerc1b2e912008-11-18 00:41:02 +0000337 /* FIXME: We assume spi_read_status_register will never fail. */
hailfingerffcf81a2008-11-03 00:02:11 +0000338 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
339 sleep(1);
340 return 0;
341}
342
stuge2bb6ab32008-05-10 23:07:52 +0000343int spi_chip_erase_c7(struct flashchip *flash)
hailfingerf71c0ac2007-10-18 00:24:07 +0000344{
uwefa98ca12008-10-18 21:14:13 +0000345 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
hailfingerc1b2e912008-11-18 00:41:02 +0000346 int result;
uwefa98ca12008-10-18 21:14:13 +0000347
hailfingerc1b2e912008-11-18 00:41:02 +0000348 result = spi_disable_blockprotect();
349 if (result) {
350 printf_debug("spi_disable_blockprotect failed\n");
351 return result;
352 }
353 result = spi_write_enable();
354 if (result) {
355 printf_debug("spi_write_enable failed\n");
356 return result;
357 }
hailfingerf71c0ac2007-10-18 00:24:07 +0000358 /* Send CE (Chip Erase) */
hailfingerc1b2e912008-11-18 00:41:02 +0000359 result = spi_command(sizeof(cmd), 0, cmd, NULL);
360 if (result) {
361 printf_debug("spi_chip_erase_60 failed sending erase\n");
362 return result;
363 }
hailfinger1b24dbb2007-10-22 16:15:28 +0000364 /* Wait until the Write-In-Progress bit is cleared.
365 * This usually takes 1-85 s, so wait in 1 s steps.
366 */
hailfingerc1b2e912008-11-18 00:41:02 +0000367 /* FIXME: We assume spi_read_status_register will never fail. */
stuge2bb6ab32008-05-10 23:07:52 +0000368 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfingerf71c0ac2007-10-18 00:24:07 +0000369 sleep(1);
hailfingerf71c0ac2007-10-18 00:24:07 +0000370 return 0;
371}
372
hailfingerc1b2e912008-11-18 00:41:02 +0000373int spi_chip_erase_60_c7(struct flashchip *flash)
374{
375 int result;
376 result = spi_chip_erase_60(flash);
377 if (result) {
378 printf_debug("spi_chip_erase_60 failed, trying c7\n");
379 result = spi_chip_erase_c7(flash);
380 }
381 return result;
382}
383
hailfingerffcf81a2008-11-03 00:02:11 +0000384int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
385{
386 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
387
388 cmd[1] = (addr & 0x00ff0000) >> 16;
389 cmd[2] = (addr & 0x0000ff00) >> 8;
390 cmd[3] = (addr & 0x000000ff);
391 spi_write_enable();
392 /* Send BE (Block Erase) */
393 spi_command(sizeof(cmd), 0, cmd, NULL);
394 /* Wait until the Write-In-Progress bit is cleared.
395 * This usually takes 100-4000 ms, so wait in 100 ms steps.
396 */
397 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
398 usleep(100 * 1000);
399 return 0;
400}
401
hailfinger1b24dbb2007-10-22 16:15:28 +0000402/* Block size is usually
403 * 64k for Macronix
404 * 32k for SST
405 * 4-32k non-uniform for EON
406 */
stuge2bb6ab32008-05-10 23:07:52 +0000407int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
hailfinger1b24dbb2007-10-22 16:15:28 +0000408{
uwefa98ca12008-10-18 21:14:13 +0000409 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 };
hailfinger1b24dbb2007-10-22 16:15:28 +0000410
411 cmd[1] = (addr & 0x00ff0000) >> 16;
412 cmd[2] = (addr & 0x0000ff00) >> 8;
413 cmd[3] = (addr & 0x000000ff);
stuge2bb6ab32008-05-10 23:07:52 +0000414 spi_write_enable();
hailfinger1b24dbb2007-10-22 16:15:28 +0000415 /* Send BE (Block Erase) */
stuge494b4eb2008-07-07 06:38:51 +0000416 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfinger1b24dbb2007-10-22 16:15:28 +0000417 /* Wait until the Write-In-Progress bit is cleared.
418 * This usually takes 100-4000 ms, so wait in 100 ms steps.
419 */
stuge2bb6ab32008-05-10 23:07:52 +0000420 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfinger1b24dbb2007-10-22 16:15:28 +0000421 usleep(100 * 1000);
422 return 0;
423}
424
stepan0f7bff02008-10-29 22:13:20 +0000425int spi_chip_erase_d8(struct flashchip *flash)
426{
427 int i, rc = 0;
428 int total_size = flash->total_size * 1024;
429 int erase_size = 64 * 1024;
430
431 spi_disable_blockprotect();
432
433 printf("Erasing chip: \n");
434
435 for (i = 0; i < total_size / erase_size; i++) {
436 rc = spi_block_erase_d8(flash, i * erase_size);
437 if (rc) {
438 printf("Error erasing block at 0x%x\n", i);
439 break;
440 }
441 }
442
443 printf("\n");
444
445 return rc;
446}
447
hailfinger1b24dbb2007-10-22 16:15:28 +0000448/* Sector size is usually 4k, though Macronix eliteflash has 64k */
stuge2bb6ab32008-05-10 23:07:52 +0000449int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
hailfinger1b24dbb2007-10-22 16:15:28 +0000450{
uwefa98ca12008-10-18 21:14:13 +0000451 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE };
hailfinger1b24dbb2007-10-22 16:15:28 +0000452 cmd[1] = (addr & 0x00ff0000) >> 16;
453 cmd[2] = (addr & 0x0000ff00) >> 8;
454 cmd[3] = (addr & 0x000000ff);
455
stuge2bb6ab32008-05-10 23:07:52 +0000456 spi_write_enable();
hailfinger1b24dbb2007-10-22 16:15:28 +0000457 /* Send SE (Sector Erase) */
stuge494b4eb2008-07-07 06:38:51 +0000458 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfinger1b24dbb2007-10-22 16:15:28 +0000459 /* Wait until the Write-In-Progress bit is cleared.
460 * This usually takes 15-800 ms, so wait in 10 ms steps.
461 */
stuge2bb6ab32008-05-10 23:07:52 +0000462 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfinger1b24dbb2007-10-22 16:15:28 +0000463 usleep(10 * 1000);
464 return 0;
465}
466
hailfingerb8f7e882008-01-19 00:04:46 +0000467/*
468 * This is according the SST25VF016 datasheet, who knows it is more
469 * generic that this...
470 */
hailfingerc1b2e912008-11-18 00:41:02 +0000471int spi_write_status_register(int status)
hailfingerb8f7e882008-01-19 00:04:46 +0000472{
uwefa98ca12008-10-18 21:14:13 +0000473 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
474 { JEDEC_WRSR, (unsigned char)status };
hailfingerb8f7e882008-01-19 00:04:46 +0000475
476 /* Send WRSR (Write Status Register) */
hailfingerc1b2e912008-11-18 00:41:02 +0000477 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerb8f7e882008-01-19 00:04:46 +0000478}
479
480void spi_byte_program(int address, uint8_t byte)
481{
uwefa98ca12008-10-18 21:14:13 +0000482 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
483 JEDEC_BYTE_PROGRAM,
484 (address >> 16) & 0xff,
485 (address >> 8) & 0xff,
486 (address >> 0) & 0xff,
hailfingerb8f7e882008-01-19 00:04:46 +0000487 byte
488 };
489
490 /* Send Byte-Program */
stuge494b4eb2008-07-07 06:38:51 +0000491 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerb8f7e882008-01-19 00:04:46 +0000492}
493
hailfingerc1b2e912008-11-18 00:41:02 +0000494int spi_disable_blockprotect(void)
hailfingerb8f7e882008-01-19 00:04:46 +0000495{
496 uint8_t status;
hailfingerc1b2e912008-11-18 00:41:02 +0000497 int result;
hailfingerb8f7e882008-01-19 00:04:46 +0000498
stuge2bb6ab32008-05-10 23:07:52 +0000499 status = spi_read_status_register();
hailfingerb8f7e882008-01-19 00:04:46 +0000500 /* If there is block protection in effect, unprotect it first. */
501 if ((status & 0x3c) != 0) {
502 printf_debug("Some block protection in effect, disabling\n");
hailfingerc1b2e912008-11-18 00:41:02 +0000503 result = spi_write_enable();
504 if (result) {
505 printf_debug("spi_write_enable failed\n");
506 return result;
507 }
508 result = spi_write_status_register(status & ~0x3c);
509 if (result) {
510 printf_debug("spi_write_status_register failed\n");
511 return result;
512 }
hailfingerb8f7e882008-01-19 00:04:46 +0000513 }
hailfingerc1b2e912008-11-18 00:41:02 +0000514 return 0;
hailfingerb8f7e882008-01-19 00:04:46 +0000515}
516
hailfingerc1b2e912008-11-18 00:41:02 +0000517int spi_nbyte_read(int address, uint8_t *bytes, int len)
hailfingerb8f7e882008-01-19 00:04:46 +0000518{
uwefa98ca12008-10-18 21:14:13 +0000519 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
520 JEDEC_READ,
hailfinger9cd4cf12008-01-22 14:37:31 +0000521 (address >> 16) & 0xff,
522 (address >> 8) & 0xff,
523 (address >> 0) & 0xff,
hailfingerb8f7e882008-01-19 00:04:46 +0000524 };
525
526 /* Send Read */
hailfingerc1b2e912008-11-18 00:41:02 +0000527 return spi_command(sizeof(cmd), len, cmd, bytes);
hailfingerb8f7e882008-01-19 00:04:46 +0000528}
529
stuge2bb6ab32008-05-10 23:07:52 +0000530int spi_chip_read(struct flashchip *flash, uint8_t *buf)
hailfingerb8f7e882008-01-19 00:04:46 +0000531{
stepan3bdf6182008-06-30 23:45:22 +0000532 switch (flashbus) {
533 case BUS_TYPE_IT87XX_SPI:
hailfinger2c361e42008-05-13 23:03:12 +0000534 return it8716f_spi_chip_read(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000535 case BUS_TYPE_ICH7_SPI:
536 case BUS_TYPE_ICH9_SPI:
537 case BUS_TYPE_VIA_SPI:
ruik9bc51c02008-06-30 21:38:30 +0000538 return ich_spi_read(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000539 default:
uwefa98ca12008-10-18 21:14:13 +0000540 printf_debug
541 ("%s called, but no SPI chipset/strapping detected\n",
542 __FUNCTION__);
stepan3bdf6182008-06-30 23:45:22 +0000543 }
544
hailfinger2c361e42008-05-13 23:03:12 +0000545 return 1;
hailfingerb8f7e882008-01-19 00:04:46 +0000546}
547
hailfinger2c361e42008-05-13 23:03:12 +0000548int spi_chip_write(struct flashchip *flash, uint8_t *buf)
549{
stepan3bdf6182008-06-30 23:45:22 +0000550 switch (flashbus) {
551 case BUS_TYPE_IT87XX_SPI:
hailfinger2c361e42008-05-13 23:03:12 +0000552 return it8716f_spi_chip_write(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000553 case BUS_TYPE_ICH7_SPI:
554 case BUS_TYPE_ICH9_SPI:
555 case BUS_TYPE_VIA_SPI:
ruik9bc51c02008-06-30 21:38:30 +0000556 return ich_spi_write(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000557 default:
uwefa98ca12008-10-18 21:14:13 +0000558 printf_debug
559 ("%s called, but no SPI chipset/strapping detected\n",
560 __FUNCTION__);
stepan3bdf6182008-06-30 23:45:22 +0000561 }
562
hailfinger2c361e42008-05-13 23:03:12 +0000563 return 1;
hailfingerf71c0ac2007-10-18 00:24:07 +0000564}