blob: 690b277592e6f55a774d9f2818fea673c77ebf8e [file] [log] [blame]
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -07001/*
2 * SPI flash interface
3 *
4 * Copyright (C) 2008 Atmel Corporation
5 * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
Aaron Durbin899d13d2015-05-15 23:39:23 -050010#include <boot_device.h>
Dan Ehrenberga5aac762015-01-08 10:29:19 -080011#include <cbfs.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100012#include <cpu/x86/smm.h>
13#include <delay.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070014#include <stdlib.h>
15#include <string.h>
Zheng Bao600784e2013-02-07 17:30:23 +080016#include <spi-generic.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070017#include <spi_flash.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100018
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070019#include "spi_flash_internal.h"
Dave Frodinc50c0ab2014-06-11 12:53:47 -060020#include <timer.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070021
Dan Ehrenberga5aac762015-01-08 10:29:19 -080022static struct spi_flash *spi_flash_dev = NULL;
23
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070024static void spi_flash_addr(u32 addr, u8 *cmd)
25{
26 /* cmd[0] is actual command */
27 cmd[1] = addr >> 16;
28 cmd[2] = addr >> 8;
29 cmd[3] = addr >> 0;
30}
31
David Hendricksf101bbe2014-03-21 19:13:34 -070032/*
33 * If atomic sequencing is used, the cycle type is known to the SPI
34 * controller so that it can perform consecutive transfers and arbitrate
35 * automatically. Otherwise the SPI controller transfers whatever the
36 * user requests immediately, without regard to sequence. Atomic
37 * sequencing is commonly used on x86 platforms.
38 *
39 * SPI flash commands are simple two-step sequences. The command byte is
40 * always written first and may be followed by an address. Then data is
41 * either read or written. For atomic sequencing we'll pass everything into
42 * spi_xfer() at once and let the controller handle the details. Otherwise
43 * we will write all output bytes first and then read if necessary.
44 *
45 * FIXME: This really should be abstracted better, but that will
46 * require overhauling the entire SPI infrastructure.
47 */
48static int do_spi_flash_cmd(struct spi_slave *spi, const void *dout,
49 unsigned int bytes_out, void *din, unsigned int bytes_in)
50{
51 int ret = 1;
52
David Hendricks032c8432014-04-11 19:48:55 -070053 if (spi_claim_bus(spi))
54 return ret;
55
David Hendricksf101bbe2014-03-21 19:13:34 -070056#if CONFIG_SPI_ATOMIC_SEQUENCING == 1
57 if (spi_xfer(spi, dout, bytes_out, din, bytes_in) < 0)
58 goto done;
59#else
60 if (dout && bytes_out) {
61 if (spi_xfer(spi, dout, bytes_out, NULL, 0) < 0)
62 goto done;
63 }
64
65 if (din && bytes_in) {
66 if (spi_xfer(spi, NULL, 0, din, bytes_in) < 0)
67 goto done;
68 }
69#endif
70
71 ret = 0;
72done:
David Hendricks032c8432014-04-11 19:48:55 -070073 spi_release_bus(spi);
David Hendricksf101bbe2014-03-21 19:13:34 -070074 return ret;
75}
76
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070077int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
78{
David Hendricksf101bbe2014-03-21 19:13:34 -070079 int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070080 if (ret)
81 printk(BIOS_WARNING, "SF: Failed to send command %02x: %d\n", cmd, ret);
82
83 return ret;
84}
85
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -080086static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
87 size_t cmd_len, void *data, size_t data_len)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070088{
David Hendricksf101bbe2014-03-21 19:13:34 -070089 int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070090 if (ret) {
91 printk(BIOS_WARNING, "SF: Failed to send read command (%zu bytes): %d\n",
92 data_len, ret);
93 }
94
95 return ret;
96}
97
Julius Werner8d8799a2014-12-19 16:11:14 -080098/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */
99#pragma GCC diagnostic push
100#pragma GCC diagnostic ignored "-Wstack-usage="
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700101int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
102 const void *data, size_t data_len)
103{
104 int ret;
105 u8 buff[cmd_len + data_len];
106 memcpy(buff, cmd, cmd_len);
107 memcpy(buff + cmd_len, data, data_len);
108
David Hendricksf101bbe2014-03-21 19:13:34 -0700109 ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700110 if (ret) {
111 printk(BIOS_WARNING, "SF: Failed to send write command (%zu bytes): %d\n",
112 data_len, ret);
113 }
114
115 return ret;
116}
Julius Werner8d8799a2014-12-19 16:11:14 -0800117#pragma GCC diagnostic pop
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700118
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800119static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd,
120 size_t cmd_len, u32 offset,
121 size_t len, void *data)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700122{
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800123 while (len) {
124 size_t transfer_size;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700125
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800126 if (spi->max_transfer_size)
127 transfer_size = min(len, spi->max_transfer_size);
128 else
129 transfer_size = len;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700130
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800131 spi_flash_addr(offset, cmd);
132
133 if (spi_flash_cmd_read(spi, cmd, cmd_len, data, transfer_size))
134 break;
135
136 offset += transfer_size;
137 data = (void *)((uintptr_t)data + transfer_size);
138 len -= transfer_size;
139 }
140
141 return len != 0;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700142}
143
144int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
145 size_t len, void *data)
146{
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700147 u8 cmd[5];
148
149 cmd[0] = CMD_READ_ARRAY_FAST;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700150 cmd[4] = 0x00;
151
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800152 return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
153 offset, len, data);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700154}
155
156int spi_flash_cmd_read_slow(struct spi_flash *flash, u32 offset,
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800157 size_t len, void *data)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700158{
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700159 u8 cmd[4];
160
161 cmd[0] = CMD_READ_ARRAY_SLOW;
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800162 return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
163 offset, len, data);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700164}
165
166int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
167 u8 cmd, u8 poll_bit)
168{
169 struct spi_slave *spi = flash->spi;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700170 int ret;
171 u8 status;
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600172 struct mono_time current, end;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700173
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600174 timer_monotonic_get(&current);
175 end = current;
176 mono_time_add_msecs(&end, timeout);
177
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700178 do {
179 ret = spi_flash_cmd_read(spi, &cmd, 1, &status, 1);
180 if (ret)
181 return -1;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700182 if ((status & poll_bit) == 0)
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600183 return 0;
184 timer_monotonic_get(&current);
185 } while (!mono_time_after(&current, &end));
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700186
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600187 printk(BIOS_DEBUG, "SF: timeout at %ld msec\n",timeout);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700188 return -1;
189}
190
191int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
192{
193 return spi_flash_cmd_poll_bit(flash, timeout,
194 CMD_READ_STATUS, STATUS_WIP);
195}
196
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800197int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700198{
199 u32 start, end, erase_size;
200 int ret;
201 u8 cmd[4];
202
203 erase_size = flash->sector_size;
204 if (offset % erase_size || len % erase_size) {
205 printk(BIOS_WARNING, "SF: Erase offset/length not multiple of erase size\n");
206 return -1;
207 }
208
Martin Roth3316cf22012-12-05 16:22:54 -0700209 flash->spi->rw = SPI_WRITE_FLAG;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700210
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800211 cmd[0] = flash->erase_cmd;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700212 start = offset;
213 end = start + len;
214
215 while (offset < end) {
216 spi_flash_addr(offset, cmd);
217 offset += erase_size;
218
Marc Jones747127d2012-12-03 22:16:29 -0700219#if CONFIG_DEBUG_SPI_FLASH
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700220 printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
221 cmd[2], cmd[3], offset);
Marc Jones747127d2012-12-03 22:16:29 -0700222#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700223 ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
224 if (ret)
225 goto out;
226
227 ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
228 if (ret)
229 goto out;
230
231 ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
232 if (ret)
233 goto out;
234 }
235
236 printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start);
237
Patrick Georgi20959ba2012-05-12 23:30:36 +0200238out:
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700239 return ret;
240}
241
Duncan Lauriefb032392015-01-15 15:28:46 -0800242int spi_flash_cmd_status(struct spi_flash *flash, u8 *reg)
243{
244 return spi_flash_cmd(flash->spi, flash->status_cmd, reg, sizeof(*reg));
245}
246
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700247/*
248 * The following table holds all device probe functions
249 *
250 * shift: number of continuation bytes before the ID
251 * idcode: the expected IDCODE or 0xff for non JEDEC devices
252 * probe: the function to call
253 *
254 * Non JEDEC devices should be ordered in the table such that
255 * the probe functions with best detection algorithms come first.
256 *
257 * Several matching entries are permitted, they will be tried
258 * in sequence until a probe function returns non NULL.
259 *
260 * IDCODE_CONT_LEN may be redefined if a device needs to declare a
261 * larger "shift" value. IDCODE_PART_LEN generally shouldn't be
262 * changed. This is the max number of bytes probe functions may
263 * examine when looking up part-specific identification info.
264 *
265 * Probe functions will be given the idcode buffer starting at their
266 * manu id byte (the "idcode" in the table below). In other words,
267 * all of the continuation bytes will be skipped (the "shift" below).
268 */
269#define IDCODE_CONT_LEN 0
270#define IDCODE_PART_LEN 5
Duncan Laurie181bbdd2012-06-23 16:53:57 -0700271static struct {
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700272 const u8 shift;
273 const u8 idcode;
274 struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
275} flashes[] = {
276 /* Keep it sorted by define name */
Idwer Vollering73a10182014-02-16 00:32:13 +0000277#if CONFIG_SPI_FLASH_AMIC
278 { 0, 0x37, spi_flash_probe_amic, },
279#endif
Kyösti Mälkki96d92762014-11-11 15:04:38 +0200280#if CONFIG_SPI_FLASH_ATMEL
281 { 0, 0x1f, spi_flash_probe_atmel, },
282#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700283#if CONFIG_SPI_FLASH_EON
284 { 0, 0x1c, spi_flash_probe_eon, },
285#endif
Martin Rothbceaf7f2012-09-07 15:02:35 -0600286#if CONFIG_SPI_FLASH_GIGADEVICE
287 { 0, 0xc8, spi_flash_probe_gigadevice, },
288#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700289#if CONFIG_SPI_FLASH_MACRONIX
290 { 0, 0xc2, spi_flash_probe_macronix, },
291#endif
292#if CONFIG_SPI_FLASH_SPANSION
293 { 0, 0x01, spi_flash_probe_spansion, },
294#endif
295#if CONFIG_SPI_FLASH_SST
296 { 0, 0xbf, spi_flash_probe_sst, },
297#endif
298#if CONFIG_SPI_FLASH_STMICRO
299 { 0, 0x20, spi_flash_probe_stmicro, },
300#endif
301#if CONFIG_SPI_FLASH_WINBOND
302 { 0, 0xef, spi_flash_probe_winbond, },
303#endif
304 /* Keep it sorted by best detection */
305#if CONFIG_SPI_FLASH_STMICRO
306 { 0, 0xff, spi_flash_probe_stmicro, },
307#endif
Chris Douglassb34739b2014-02-14 13:51:26 -0500308#if CONFIG_SPI_FLASH_ADESTO
309 { 0, 0x1f, spi_flash_probe_adesto, },
310#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700311};
312#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
313
Gabe Black1e187352014-03-27 20:37:03 -0700314struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700315{
316 struct spi_slave *spi;
317 struct spi_flash *flash = NULL;
318 int ret, i, shift;
319 u8 idcode[IDCODE_LEN], *idp;
320
Gabe Black1e187352014-03-27 20:37:03 -0700321 spi = spi_setup_slave(bus, cs);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700322 if (!spi) {
323 printk(BIOS_WARNING, "SF: Failed to set up slave\n");
324 return NULL;
325 }
326
Martin Roth3316cf22012-12-05 16:22:54 -0700327 spi->rw = SPI_READ_FLAG;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700328
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100329 if (spi->force_programmer_specific && spi->programmer_specific_probe) {
330 flash = spi->programmer_specific_probe (spi);
331 if (!flash)
332 goto err_read_id;
333 goto flash_detected;
334 }
335
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700336 /* Read the ID codes */
337 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
338 if (ret)
339 goto err_read_id;
340
341#if CONFIG_DEBUG_SPI_FLASH
David Hendricksb598bb32014-03-21 19:32:09 -0700342 printk(BIOS_SPEW, "SF: Got idcode: ");
343 for (i = 0; i < sizeof(idcode); i++)
344 printk(BIOS_SPEW, "%02x ", idcode[i]);
345 printk(BIOS_SPEW, "\n");
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700346#endif
347
348 /* count the number of continuation bytes */
349 for (shift = 0, idp = idcode;
350 shift < IDCODE_CONT_LEN && *idp == 0x7f;
351 ++shift, ++idp)
352 continue;
353
354 /* search the table for matches in shift and id */
355 for (i = 0; i < ARRAY_SIZE(flashes); ++i)
356 if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
357 /* we have a match, call probe */
358 flash = flashes[i].probe(spi, idp);
359 if (flash)
360 break;
361 }
362
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100363 if (!flash && spi->programmer_specific_probe) {
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100364 flash = spi->programmer_specific_probe (spi);
365 }
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700366 if (!flash) {
367 printk(BIOS_WARNING, "SF: Unsupported manufacturer %02x\n", *idp);
368 goto err_manufacturer_probe;
369 }
370
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100371flash_detected:
David Imhoff8d4377b2015-05-03 13:47:49 +0200372 printk(BIOS_INFO, "SF: Detected %s with sector size 0x%x, total 0x%x\n",
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700373 flash->name, flash->sector_size, flash->size);
374
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800375 spi_flash_dev = flash;
376
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700377 return flash;
378
379err_manufacturer_probe:
380err_read_id:
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700381 return NULL;
382}
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800383
384/* Only the RAM stage will build in the lb_new_record symbol
385 * so only define this function if we are after that stage */
386#ifdef __RAMSTAGE__
387
388void lb_spi_flash(struct lb_header *header)
389{
390 struct lb_spi_flash *flash;
391
392 flash = (struct lb_spi_flash *)lb_new_record(header);
393
394 flash->tag = LB_TAG_SPI_FLASH;
395 flash->size = sizeof(*flash);
396
397 /* Try to get the flash device if not loaded yet */
Aaron Durbin899d13d2015-05-15 23:39:23 -0500398 if (!spi_flash_dev)
399 boot_device_init();
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800400
401 if (spi_flash_dev) {
402 flash->flash_size = spi_flash_dev->size;
403 flash->sector_size = spi_flash_dev->sector_size;
404 flash->erase_cmd = spi_flash_dev->erase_cmd;
405 } else {
406 flash->flash_size = CONFIG_ROM_SIZE;
407 /* Default 64k erase command should work on most flash.
408 * Uniform 4k erase only works on certain devices. */
409 flash->sector_size = 64 * KiB;
410 flash->erase_cmd = CMD_BLOCK_ERASE;
411 }
412}
413
414#endif