blob: a5b85f4e02ba91539aa6a6c4bb9255f1d24ce338 [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
hailfinger82893122008-05-15 03:19:49 +000064static int spi_res(unsigned char *readarr)
65{
uwefa98ca12008-10-18 21:14:13 +000066 const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
hailfinger82893122008-05-15 03:19:49 +000067
stuge494b4eb2008-07-07 06:38:51 +000068 if (spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr))
hailfinger82893122008-05-15 03:19:49 +000069 return 1;
70 printf_debug("RES returned %02x.\n", readarr[0]);
71 return 0;
72}
73
hailfingerc1b2e912008-11-18 00:41:02 +000074int spi_write_enable()
hailfingerf71c0ac2007-10-18 00:24:07 +000075{
uwefa98ca12008-10-18 21:14:13 +000076 const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN };
hailfingerf71c0ac2007-10-18 00:24:07 +000077
78 /* Send WREN (Write Enable) */
hailfingerc1b2e912008-11-18 00:41:02 +000079 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerf71c0ac2007-10-18 00:24:07 +000080}
81
hailfingerc1b2e912008-11-18 00:41:02 +000082int spi_write_disable()
hailfingerf71c0ac2007-10-18 00:24:07 +000083{
uwefa98ca12008-10-18 21:14:13 +000084 const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = { JEDEC_WRDI };
hailfingerf71c0ac2007-10-18 00:24:07 +000085
86 /* Send WRDI (Write Disable) */
hailfingerc1b2e912008-11-18 00:41:02 +000087 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerf71c0ac2007-10-18 00:24:07 +000088}
89
ruikdbe18ee2008-06-30 21:45:17 +000090static int probe_spi_rdid_generic(struct flashchip *flash, int bytes)
stepand4b13752007-10-15 21:45:29 +000091{
ruikdbe18ee2008-06-30 21:45:17 +000092 unsigned char readarr[4];
hailfinger492e3172008-02-06 22:07:58 +000093 uint32_t manuf_id;
94 uint32_t model_id;
hailfingerf1961cb2007-12-29 10:15:58 +000095
ruikdbe18ee2008-06-30 21:45:17 +000096 if (spi_rdid(readarr, bytes))
stuge7be66832008-06-24 01:22:03 +000097 return 0;
98
99 if (!oddparity(readarr[0]))
100 printf_debug("RDID byte 0 parity violation.\n");
101
102 /* Check if this is a continuation vendor ID */
103 if (readarr[0] == 0x7f) {
104 if (!oddparity(readarr[1]))
105 printf_debug("RDID byte 1 parity violation.\n");
106 manuf_id = (readarr[0] << 8) | readarr[1];
107 model_id = readarr[2];
ruikdbe18ee2008-06-30 21:45:17 +0000108 if (bytes > 3) {
109 model_id <<= 8;
110 model_id |= readarr[3];
111 }
stuge7be66832008-06-24 01:22:03 +0000112 } else {
113 manuf_id = readarr[0];
114 model_id = (readarr[1] << 8) | readarr[2];
stepand4b13752007-10-15 21:45:29 +0000115 }
116
uwefa98ca12008-10-18 21:14:13 +0000117 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id,
118 model_id);
stuge7be66832008-06-24 01:22:03 +0000119
uwefa98ca12008-10-18 21:14:13 +0000120 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
stuge7be66832008-06-24 01:22:03 +0000121 /* Print the status register to tell the
122 * user about possible write protection.
123 */
124 spi_prettyprint_status_register(flash);
125
126 return 1;
127 }
128
129 /* Test if this is a pure vendor match. */
130 if (manuf_id == flash->manufacture_id &&
131 GENERIC_DEVICE_ID == flash->model_id)
132 return 1;
133
stepand4b13752007-10-15 21:45:29 +0000134 return 0;
135}
136
uwefa98ca12008-10-18 21:14:13 +0000137int probe_spi_rdid(struct flashchip *flash)
138{
ruikdbe18ee2008-06-30 21:45:17 +0000139 return probe_spi_rdid_generic(flash, 3);
140}
141
142/* support 4 bytes flash ID */
uwefa98ca12008-10-18 21:14:13 +0000143int probe_spi_rdid4(struct flashchip *flash)
144{
ruikdbe18ee2008-06-30 21:45:17 +0000145 /* only some SPI chipsets support 4 bytes commands */
stepan3bdf6182008-06-30 23:45:22 +0000146 switch (flashbus) {
147 case BUS_TYPE_ICH7_SPI:
148 case BUS_TYPE_ICH9_SPI:
149 case BUS_TYPE_VIA_SPI:
150 return probe_spi_rdid_generic(flash, 4);
151 default:
152 printf_debug("4b ID not supported on this SPI controller\n");
153 }
154
155 return 0;
ruikdbe18ee2008-06-30 21:45:17 +0000156}
157
hailfinger82893122008-05-15 03:19:49 +0000158int probe_spi_res(struct flashchip *flash)
159{
160 unsigned char readarr[3];
161 uint32_t model_id;
stuge7be66832008-06-24 01:22:03 +0000162
hailfinger915cc852008-11-27 22:48:48 +0000163 /* Check if RDID was successful and did not return 0xff 0xff 0xff.
164 * In that case, RES is pointless.
165 */
166 if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
167 (readarr[1] != 0xff) || (readarr[2] != 0xff)))
stuge7be66832008-06-24 01:22:03 +0000168 return 0;
hailfinger82893122008-05-15 03:19:49 +0000169
stuge7be66832008-06-24 01:22:03 +0000170 if (spi_res(readarr))
171 return 0;
172
173 model_id = readarr[0];
174 printf_debug("%s: id 0x%x\n", __FUNCTION__, model_id);
175 if (model_id != flash->model_id)
176 return 0;
177
178 /* Print the status register to tell the
179 * user about possible write protection.
180 */
181 spi_prettyprint_status_register(flash);
182 return 1;
hailfinger82893122008-05-15 03:19:49 +0000183}
184
stuge2bb6ab32008-05-10 23:07:52 +0000185uint8_t spi_read_status_register()
hailfingerf71c0ac2007-10-18 00:24:07 +0000186{
uwefa98ca12008-10-18 21:14:13 +0000187 const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
stuge494b4eb2008-07-07 06:38:51 +0000188 unsigned char readarr[JEDEC_RDSR_INSIZE];
hailfingerf71c0ac2007-10-18 00:24:07 +0000189
190 /* Read Status Register */
stuge494b4eb2008-07-07 06:38:51 +0000191 spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
hailfingerf71c0ac2007-10-18 00:24:07 +0000192 return readarr[0];
193}
194
hailfingerb8f7e882008-01-19 00:04:46 +0000195/* Prettyprint the status register. Common definitions.
196 */
197void spi_prettyprint_status_register_common(uint8_t status)
198{
199 printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
uwefa98ca12008-10-18 21:14:13 +0000200 "%sset\n", (status & (1 << 5)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000201 printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
uwefa98ca12008-10-18 21:14:13 +0000202 "%sset\n", (status & (1 << 4)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000203 printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
uwefa98ca12008-10-18 21:14:13 +0000204 "%sset\n", (status & (1 << 3)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000205 printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
uwefa98ca12008-10-18 21:14:13 +0000206 "%sset\n", (status & (1 << 2)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000207 printf_debug("Chip status register: Write Enable Latch (WEL) is "
uwefa98ca12008-10-18 21:14:13 +0000208 "%sset\n", (status & (1 << 1)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000209 printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
uwefa98ca12008-10-18 21:14:13 +0000210 "%sset\n", (status & (1 << 0)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000211}
212
hailfingerf1961cb2007-12-29 10:15:58 +0000213/* Prettyprint the status register. Works for
214 * ST M25P series
215 * MX MX25L series
216 */
hailfingerb8f7e882008-01-19 00:04:46 +0000217void spi_prettyprint_status_register_st_m25p(uint8_t status)
hailfingerf1961cb2007-12-29 10:15:58 +0000218{
219 printf_debug("Chip status register: Status Register Write Disable "
uwefa98ca12008-10-18 21:14:13 +0000220 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
hailfingerf1961cb2007-12-29 10:15:58 +0000221 printf_debug("Chip status register: Bit 6 is "
uwefa98ca12008-10-18 21:14:13 +0000222 "%sset\n", (status & (1 << 6)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000223 spi_prettyprint_status_register_common(status);
hailfingerf1961cb2007-12-29 10:15:58 +0000224}
225
hailfingerb8f7e882008-01-19 00:04:46 +0000226/* Prettyprint the status register. Works for
227 * SST 25VF016
228 */
229void spi_prettyprint_status_register_sst25vf016(uint8_t status)
230{
hailfinger9cd4cf12008-01-22 14:37:31 +0000231 const char *bpt[] = {
hailfingerb8f7e882008-01-19 00:04:46 +0000232 "none",
233 "1F0000H-1FFFFFH",
234 "1E0000H-1FFFFFH",
235 "1C0000H-1FFFFFH",
236 "180000H-1FFFFFH",
237 "100000H-1FFFFFH",
hailfinger9cd4cf12008-01-22 14:37:31 +0000238 "all", "all"
hailfingerb8f7e882008-01-19 00:04:46 +0000239 };
240 printf_debug("Chip status register: Block Protect Write Disable "
uwefa98ca12008-10-18 21:14:13 +0000241 "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000242 printf_debug("Chip status register: Auto Address Increment Programming "
uwefa98ca12008-10-18 21:14:13 +0000243 "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
hailfingerb8f7e882008-01-19 00:04:46 +0000244 spi_prettyprint_status_register_common(status);
245 printf_debug("Resulting block protection : %s\n",
uwefa98ca12008-10-18 21:14:13 +0000246 bpt[(status & 0x1c) >> 2]);
hailfingerb8f7e882008-01-19 00:04:46 +0000247}
248
249void spi_prettyprint_status_register(struct flashchip *flash)
hailfingerf1961cb2007-12-29 10:15:58 +0000250{
251 uint8_t status;
252
stuge2bb6ab32008-05-10 23:07:52 +0000253 status = spi_read_status_register();
hailfingerf1961cb2007-12-29 10:15:58 +0000254 printf_debug("Chip status register is %02x\n", status);
255 switch (flash->manufacture_id) {
256 case ST_ID:
hailfinger8b869132008-05-15 22:32:08 +0000257 if (((flash->model_id & 0xff00) == 0x2000) ||
258 ((flash->model_id & 0xff00) == 0x2500))
259 spi_prettyprint_status_register_st_m25p(status);
260 break;
hailfingerf1961cb2007-12-29 10:15:58 +0000261 case MX_ID:
262 if ((flash->model_id & 0xff00) == 0x2000)
hailfingerb8f7e882008-01-19 00:04:46 +0000263 spi_prettyprint_status_register_st_m25p(status);
264 break;
265 case SST_ID:
266 if (flash->model_id == SST_25VF016B)
267 spi_prettyprint_status_register_sst25vf016(status);
hailfingerf1961cb2007-12-29 10:15:58 +0000268 break;
269 }
270}
uwefa98ca12008-10-18 21:14:13 +0000271
hailfingerffcf81a2008-11-03 00:02:11 +0000272int spi_chip_erase_60(struct flashchip *flash)
273{
274 const unsigned char cmd[JEDEC_CE_60_OUTSIZE] = {JEDEC_CE_60};
hailfingerc1b2e912008-11-18 00:41:02 +0000275 int result;
hailfingerffcf81a2008-11-03 00:02:11 +0000276
hailfingerc1b2e912008-11-18 00:41:02 +0000277 result = spi_disable_blockprotect();
278 if (result) {
279 printf_debug("spi_disable_blockprotect failed\n");
280 return result;
281 }
282 result = spi_write_enable();
283 if (result) {
284 printf_debug("spi_write_enable failed\n");
285 return result;
286 }
hailfingerffcf81a2008-11-03 00:02:11 +0000287 /* Send CE (Chip Erase) */
hailfingerc1b2e912008-11-18 00:41:02 +0000288 result = spi_command(sizeof(cmd), 0, cmd, NULL);
289 if (result) {
290 printf_debug("spi_chip_erase_60 failed sending erase\n");
291 return result;
292 }
hailfingerffcf81a2008-11-03 00:02:11 +0000293 /* Wait until the Write-In-Progress bit is cleared.
294 * This usually takes 1-85 s, so wait in 1 s steps.
295 */
hailfingerc1b2e912008-11-18 00:41:02 +0000296 /* FIXME: We assume spi_read_status_register will never fail. */
hailfingerffcf81a2008-11-03 00:02:11 +0000297 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
298 sleep(1);
299 return 0;
300}
301
stuge2bb6ab32008-05-10 23:07:52 +0000302int spi_chip_erase_c7(struct flashchip *flash)
hailfingerf71c0ac2007-10-18 00:24:07 +0000303{
uwefa98ca12008-10-18 21:14:13 +0000304 const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = { JEDEC_CE_C7 };
hailfingerc1b2e912008-11-18 00:41:02 +0000305 int result;
uwefa98ca12008-10-18 21:14:13 +0000306
hailfingerc1b2e912008-11-18 00:41:02 +0000307 result = spi_disable_blockprotect();
308 if (result) {
309 printf_debug("spi_disable_blockprotect failed\n");
310 return result;
311 }
312 result = spi_write_enable();
313 if (result) {
314 printf_debug("spi_write_enable failed\n");
315 return result;
316 }
hailfingerf71c0ac2007-10-18 00:24:07 +0000317 /* Send CE (Chip Erase) */
hailfingerc1b2e912008-11-18 00:41:02 +0000318 result = spi_command(sizeof(cmd), 0, cmd, NULL);
319 if (result) {
320 printf_debug("spi_chip_erase_60 failed sending erase\n");
321 return result;
322 }
hailfinger1b24dbb2007-10-22 16:15:28 +0000323 /* Wait until the Write-In-Progress bit is cleared.
324 * This usually takes 1-85 s, so wait in 1 s steps.
325 */
hailfingerc1b2e912008-11-18 00:41:02 +0000326 /* FIXME: We assume spi_read_status_register will never fail. */
stuge2bb6ab32008-05-10 23:07:52 +0000327 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfingerf71c0ac2007-10-18 00:24:07 +0000328 sleep(1);
hailfingerf71c0ac2007-10-18 00:24:07 +0000329 return 0;
330}
331
hailfingerc1b2e912008-11-18 00:41:02 +0000332int spi_chip_erase_60_c7(struct flashchip *flash)
333{
334 int result;
335 result = spi_chip_erase_60(flash);
336 if (result) {
337 printf_debug("spi_chip_erase_60 failed, trying c7\n");
338 result = spi_chip_erase_c7(flash);
339 }
340 return result;
341}
342
hailfingerffcf81a2008-11-03 00:02:11 +0000343int spi_block_erase_52(const struct flashchip *flash, unsigned long addr)
344{
345 unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52};
346
347 cmd[1] = (addr & 0x00ff0000) >> 16;
348 cmd[2] = (addr & 0x0000ff00) >> 8;
349 cmd[3] = (addr & 0x000000ff);
350 spi_write_enable();
351 /* Send BE (Block Erase) */
352 spi_command(sizeof(cmd), 0, cmd, NULL);
353 /* Wait until the Write-In-Progress bit is cleared.
354 * This usually takes 100-4000 ms, so wait in 100 ms steps.
355 */
356 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
357 usleep(100 * 1000);
358 return 0;
359}
360
hailfinger1b24dbb2007-10-22 16:15:28 +0000361/* Block size is usually
362 * 64k for Macronix
363 * 32k for SST
364 * 4-32k non-uniform for EON
365 */
stuge2bb6ab32008-05-10 23:07:52 +0000366int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
hailfinger1b24dbb2007-10-22 16:15:28 +0000367{
uwefa98ca12008-10-18 21:14:13 +0000368 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 };
hailfinger1b24dbb2007-10-22 16:15:28 +0000369
370 cmd[1] = (addr & 0x00ff0000) >> 16;
371 cmd[2] = (addr & 0x0000ff00) >> 8;
372 cmd[3] = (addr & 0x000000ff);
stuge2bb6ab32008-05-10 23:07:52 +0000373 spi_write_enable();
hailfinger1b24dbb2007-10-22 16:15:28 +0000374 /* Send BE (Block Erase) */
stuge494b4eb2008-07-07 06:38:51 +0000375 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfinger1b24dbb2007-10-22 16:15:28 +0000376 /* Wait until the Write-In-Progress bit is cleared.
377 * This usually takes 100-4000 ms, so wait in 100 ms steps.
378 */
stuge2bb6ab32008-05-10 23:07:52 +0000379 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfinger1b24dbb2007-10-22 16:15:28 +0000380 usleep(100 * 1000);
381 return 0;
382}
383
stepan0f7bff02008-10-29 22:13:20 +0000384int spi_chip_erase_d8(struct flashchip *flash)
385{
386 int i, rc = 0;
387 int total_size = flash->total_size * 1024;
388 int erase_size = 64 * 1024;
389
390 spi_disable_blockprotect();
391
392 printf("Erasing chip: \n");
393
394 for (i = 0; i < total_size / erase_size; i++) {
395 rc = spi_block_erase_d8(flash, i * erase_size);
396 if (rc) {
397 printf("Error erasing block at 0x%x\n", i);
398 break;
399 }
400 }
401
402 printf("\n");
403
404 return rc;
405}
406
hailfinger1b24dbb2007-10-22 16:15:28 +0000407/* Sector size is usually 4k, though Macronix eliteflash has 64k */
stuge2bb6ab32008-05-10 23:07:52 +0000408int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
hailfinger1b24dbb2007-10-22 16:15:28 +0000409{
uwefa98ca12008-10-18 21:14:13 +0000410 unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE };
hailfinger1b24dbb2007-10-22 16:15:28 +0000411 cmd[1] = (addr & 0x00ff0000) >> 16;
412 cmd[2] = (addr & 0x0000ff00) >> 8;
413 cmd[3] = (addr & 0x000000ff);
414
stuge2bb6ab32008-05-10 23:07:52 +0000415 spi_write_enable();
hailfinger1b24dbb2007-10-22 16:15:28 +0000416 /* Send SE (Sector Erase) */
stuge494b4eb2008-07-07 06:38:51 +0000417 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfinger1b24dbb2007-10-22 16:15:28 +0000418 /* Wait until the Write-In-Progress bit is cleared.
419 * This usually takes 15-800 ms, so wait in 10 ms steps.
420 */
stuge2bb6ab32008-05-10 23:07:52 +0000421 while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
hailfinger1b24dbb2007-10-22 16:15:28 +0000422 usleep(10 * 1000);
423 return 0;
424}
425
hailfingerb8f7e882008-01-19 00:04:46 +0000426/*
427 * This is according the SST25VF016 datasheet, who knows it is more
428 * generic that this...
429 */
hailfingerc1b2e912008-11-18 00:41:02 +0000430int spi_write_status_register(int status)
hailfingerb8f7e882008-01-19 00:04:46 +0000431{
uwefa98ca12008-10-18 21:14:13 +0000432 const unsigned char cmd[JEDEC_WRSR_OUTSIZE] =
433 { JEDEC_WRSR, (unsigned char)status };
hailfingerb8f7e882008-01-19 00:04:46 +0000434
435 /* Send WRSR (Write Status Register) */
hailfingerc1b2e912008-11-18 00:41:02 +0000436 return spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerb8f7e882008-01-19 00:04:46 +0000437}
438
439void spi_byte_program(int address, uint8_t byte)
440{
uwefa98ca12008-10-18 21:14:13 +0000441 const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {
442 JEDEC_BYTE_PROGRAM,
443 (address >> 16) & 0xff,
444 (address >> 8) & 0xff,
445 (address >> 0) & 0xff,
hailfingerb8f7e882008-01-19 00:04:46 +0000446 byte
447 };
448
449 /* Send Byte-Program */
stuge494b4eb2008-07-07 06:38:51 +0000450 spi_command(sizeof(cmd), 0, cmd, NULL);
hailfingerb8f7e882008-01-19 00:04:46 +0000451}
452
hailfingerc1b2e912008-11-18 00:41:02 +0000453int spi_disable_blockprotect(void)
hailfingerb8f7e882008-01-19 00:04:46 +0000454{
455 uint8_t status;
hailfingerc1b2e912008-11-18 00:41:02 +0000456 int result;
hailfingerb8f7e882008-01-19 00:04:46 +0000457
stuge2bb6ab32008-05-10 23:07:52 +0000458 status = spi_read_status_register();
hailfingerb8f7e882008-01-19 00:04:46 +0000459 /* If there is block protection in effect, unprotect it first. */
460 if ((status & 0x3c) != 0) {
461 printf_debug("Some block protection in effect, disabling\n");
hailfingerc1b2e912008-11-18 00:41:02 +0000462 result = spi_write_enable();
463 if (result) {
464 printf_debug("spi_write_enable failed\n");
465 return result;
466 }
467 result = spi_write_status_register(status & ~0x3c);
468 if (result) {
469 printf_debug("spi_write_status_register failed\n");
470 return result;
471 }
hailfingerb8f7e882008-01-19 00:04:46 +0000472 }
hailfingerc1b2e912008-11-18 00:41:02 +0000473 return 0;
hailfingerb8f7e882008-01-19 00:04:46 +0000474}
475
hailfingerc1b2e912008-11-18 00:41:02 +0000476int spi_nbyte_read(int address, uint8_t *bytes, int len)
hailfingerb8f7e882008-01-19 00:04:46 +0000477{
uwefa98ca12008-10-18 21:14:13 +0000478 const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
479 JEDEC_READ,
hailfinger9cd4cf12008-01-22 14:37:31 +0000480 (address >> 16) & 0xff,
481 (address >> 8) & 0xff,
482 (address >> 0) & 0xff,
hailfingerb8f7e882008-01-19 00:04:46 +0000483 };
484
485 /* Send Read */
hailfingerc1b2e912008-11-18 00:41:02 +0000486 return spi_command(sizeof(cmd), len, cmd, bytes);
hailfingerb8f7e882008-01-19 00:04:46 +0000487}
488
stuge2bb6ab32008-05-10 23:07:52 +0000489int spi_chip_read(struct flashchip *flash, uint8_t *buf)
hailfingerb8f7e882008-01-19 00:04:46 +0000490{
stepan3bdf6182008-06-30 23:45:22 +0000491 switch (flashbus) {
492 case BUS_TYPE_IT87XX_SPI:
hailfinger2c361e42008-05-13 23:03:12 +0000493 return it8716f_spi_chip_read(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000494 case BUS_TYPE_ICH7_SPI:
495 case BUS_TYPE_ICH9_SPI:
496 case BUS_TYPE_VIA_SPI:
ruik9bc51c02008-06-30 21:38:30 +0000497 return ich_spi_read(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000498 default:
uwefa98ca12008-10-18 21:14:13 +0000499 printf_debug
500 ("%s called, but no SPI chipset/strapping detected\n",
501 __FUNCTION__);
stepan3bdf6182008-06-30 23:45:22 +0000502 }
503
hailfinger2c361e42008-05-13 23:03:12 +0000504 return 1;
hailfingerb8f7e882008-01-19 00:04:46 +0000505}
506
hailfinger2c361e42008-05-13 23:03:12 +0000507int spi_chip_write(struct flashchip *flash, uint8_t *buf)
508{
stepan3bdf6182008-06-30 23:45:22 +0000509 switch (flashbus) {
510 case BUS_TYPE_IT87XX_SPI:
hailfinger2c361e42008-05-13 23:03:12 +0000511 return it8716f_spi_chip_write(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000512 case BUS_TYPE_ICH7_SPI:
513 case BUS_TYPE_ICH9_SPI:
514 case BUS_TYPE_VIA_SPI:
ruik9bc51c02008-06-30 21:38:30 +0000515 return ich_spi_write(flash, buf);
stepan3bdf6182008-06-30 23:45:22 +0000516 default:
uwefa98ca12008-10-18 21:14:13 +0000517 printf_debug
518 ("%s called, but no SPI chipset/strapping detected\n",
519 __FUNCTION__);
stepan3bdf6182008-06-30 23:45:22 +0000520 }
521
hailfinger2c361e42008-05-13 23:03:12 +0000522 return 1;
hailfingerf71c0ac2007-10-18 00:24:07 +0000523}