blob: 7ca6822ba1adfc2a0f82dcdeca87e6d20ab2ac3b [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
Furquan Shaikhc28984d2016-11-20 21:04:00 -080010#include <arch/early_variables.h>
11#include <assert.h>
Aaron Durbin899d13d2015-05-15 23:39:23 -050012#include <boot_device.h>
Dan Ehrenberga5aac762015-01-08 10:29:19 -080013#include <cbfs.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100014#include <cpu/x86/smm.h>
15#include <delay.h>
Aaron Durbinc0a823c2016-08-11 14:51:38 -050016#include <rules.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070017#include <stdlib.h>
18#include <string.h>
Zheng Bao600784e2013-02-07 17:30:23 +080019#include <spi-generic.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070020#include <spi_flash.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100021
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070022#include "spi_flash_internal.h"
Dave Frodinc50c0ab2014-06-11 12:53:47 -060023#include <timer.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070024
Dan Ehrenberga5aac762015-01-08 10:29:19 -080025static struct spi_flash *spi_flash_dev = NULL;
26
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070027static void spi_flash_addr(u32 addr, u8 *cmd)
28{
29 /* cmd[0] is actual command */
30 cmd[1] = addr >> 16;
31 cmd[2] = addr >> 8;
32 cmd[3] = addr >> 0;
33}
34
David Hendricksf101bbe2014-03-21 19:13:34 -070035/*
36 * If atomic sequencing is used, the cycle type is known to the SPI
37 * controller so that it can perform consecutive transfers and arbitrate
38 * automatically. Otherwise the SPI controller transfers whatever the
39 * user requests immediately, without regard to sequence. Atomic
40 * sequencing is commonly used on x86 platforms.
41 *
42 * SPI flash commands are simple two-step sequences. The command byte is
43 * always written first and may be followed by an address. Then data is
44 * either read or written. For atomic sequencing we'll pass everything into
45 * spi_xfer() at once and let the controller handle the details. Otherwise
46 * we will write all output bytes first and then read if necessary.
47 *
48 * FIXME: This really should be abstracted better, but that will
49 * require overhauling the entire SPI infrastructure.
50 */
51static int do_spi_flash_cmd(struct spi_slave *spi, const void *dout,
52 unsigned int bytes_out, void *din, unsigned int bytes_in)
53{
54 int ret = 1;
55
David Hendricks032c8432014-04-11 19:48:55 -070056 if (spi_claim_bus(spi))
57 return ret;
58
David Hendricksf101bbe2014-03-21 19:13:34 -070059#if CONFIG_SPI_ATOMIC_SEQUENCING == 1
60 if (spi_xfer(spi, dout, bytes_out, din, bytes_in) < 0)
61 goto done;
62#else
63 if (dout && bytes_out) {
64 if (spi_xfer(spi, dout, bytes_out, NULL, 0) < 0)
65 goto done;
66 }
67
68 if (din && bytes_in) {
69 if (spi_xfer(spi, NULL, 0, din, bytes_in) < 0)
70 goto done;
71 }
72#endif
73
74 ret = 0;
75done:
David Hendricks032c8432014-04-11 19:48:55 -070076 spi_release_bus(spi);
David Hendricksf101bbe2014-03-21 19:13:34 -070077 return ret;
78}
79
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070080int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
81{
David Hendricksf101bbe2014-03-21 19:13:34 -070082 int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070083 if (ret)
84 printk(BIOS_WARNING, "SF: Failed to send command %02x: %d\n", cmd, ret);
85
86 return ret;
87}
88
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -080089static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
90 size_t cmd_len, void *data, size_t data_len)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070091{
David Hendricksf101bbe2014-03-21 19:13:34 -070092 int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070093 if (ret) {
94 printk(BIOS_WARNING, "SF: Failed to send read command (%zu bytes): %d\n",
95 data_len, ret);
96 }
97
98 return ret;
99}
100
Julius Werner8d8799a2014-12-19 16:11:14 -0800101/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */
102#pragma GCC diagnostic push
103#pragma GCC diagnostic ignored "-Wstack-usage="
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700104int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
105 const void *data, size_t data_len)
106{
107 int ret;
108 u8 buff[cmd_len + data_len];
109 memcpy(buff, cmd, cmd_len);
110 memcpy(buff + cmd_len, data, data_len);
111
David Hendricksf101bbe2014-03-21 19:13:34 -0700112 ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700113 if (ret) {
114 printk(BIOS_WARNING, "SF: Failed to send write command (%zu bytes): %d\n",
115 data_len, ret);
116 }
117
118 return ret;
119}
Julius Werner8d8799a2014-12-19 16:11:14 -0800120#pragma GCC diagnostic pop
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700121
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800122static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd,
123 size_t cmd_len, u32 offset,
124 size_t len, void *data)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700125{
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800126 while (len) {
127 size_t transfer_size;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700128
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800129 if (spi->max_transfer_size)
130 transfer_size = min(len, spi->max_transfer_size);
131 else
132 transfer_size = len;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700133
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800134 spi_flash_addr(offset, cmd);
135
136 if (spi_flash_cmd_read(spi, cmd, cmd_len, data, transfer_size))
137 break;
138
139 offset += transfer_size;
140 data = (void *)((uintptr_t)data + transfer_size);
141 len -= transfer_size;
142 }
143
144 return len != 0;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700145}
146
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800147int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
148 size_t len, void *data)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700149{
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700150 u8 cmd[5];
151
152 cmd[0] = CMD_READ_ARRAY_FAST;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700153 cmd[4] = 0x00;
154
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800155 return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
156 offset, len, data);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700157}
158
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800159int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset,
160 size_t len, void *data)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700161{
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700162 u8 cmd[4];
163
164 cmd[0] = CMD_READ_ARRAY_SLOW;
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800165 return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
166 offset, len, data);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700167}
168
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800169int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700170 u8 cmd, u8 poll_bit)
171{
172 struct spi_slave *spi = flash->spi;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700173 int ret;
174 u8 status;
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600175 struct mono_time current, end;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700176
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600177 timer_monotonic_get(&current);
178 end = current;
179 mono_time_add_msecs(&end, timeout);
180
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700181 do {
182 ret = spi_flash_cmd_read(spi, &cmd, 1, &status, 1);
183 if (ret)
184 return -1;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700185 if ((status & poll_bit) == 0)
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600186 return 0;
187 timer_monotonic_get(&current);
188 } while (!mono_time_after(&current, &end));
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700189
Dave Frodinc50c0ab2014-06-11 12:53:47 -0600190 printk(BIOS_DEBUG, "SF: timeout at %ld msec\n",timeout);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700191 return -1;
192}
193
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800194int spi_flash_cmd_wait_ready(const struct spi_flash *flash,
195 unsigned long timeout)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700196{
197 return spi_flash_cmd_poll_bit(flash, timeout,
198 CMD_READ_STATUS, STATUS_WIP);
199}
200
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800201int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700202{
203 u32 start, end, erase_size;
204 int ret;
205 u8 cmd[4];
206
207 erase_size = flash->sector_size;
208 if (offset % erase_size || len % erase_size) {
209 printk(BIOS_WARNING, "SF: Erase offset/length not multiple of erase size\n");
210 return -1;
211 }
212
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800213 cmd[0] = flash->erase_cmd;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700214 start = offset;
215 end = start + len;
216
217 while (offset < end) {
218 spi_flash_addr(offset, cmd);
219 offset += erase_size;
220
Marc Jones747127d2012-12-03 22:16:29 -0700221#if CONFIG_DEBUG_SPI_FLASH
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700222 printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
223 cmd[2], cmd[3], offset);
Marc Jones747127d2012-12-03 22:16:29 -0700224#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700225 ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
226 if (ret)
227 goto out;
228
229 ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
230 if (ret)
231 goto out;
232
233 ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
234 if (ret)
235 goto out;
236 }
237
238 printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start);
239
Patrick Georgi20959ba2012-05-12 23:30:36 +0200240out:
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700241 return ret;
242}
243
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800244int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg)
Duncan Lauriefb032392015-01-15 15:28:46 -0800245{
246 return spi_flash_cmd(flash->spi, flash->status_cmd, reg, sizeof(*reg));
247}
248
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700249/*
250 * The following table holds all device probe functions
251 *
252 * shift: number of continuation bytes before the ID
253 * idcode: the expected IDCODE or 0xff for non JEDEC devices
254 * probe: the function to call
255 *
256 * Non JEDEC devices should be ordered in the table such that
257 * the probe functions with best detection algorithms come first.
258 *
259 * Several matching entries are permitted, they will be tried
260 * in sequence until a probe function returns non NULL.
261 *
262 * IDCODE_CONT_LEN may be redefined if a device needs to declare a
263 * larger "shift" value. IDCODE_PART_LEN generally shouldn't be
264 * changed. This is the max number of bytes probe functions may
265 * examine when looking up part-specific identification info.
266 *
267 * Probe functions will be given the idcode buffer starting at their
268 * manu id byte (the "idcode" in the table below). In other words,
269 * all of the continuation bytes will be skipped (the "shift" below).
270 */
271#define IDCODE_CONT_LEN 0
272#define IDCODE_PART_LEN 5
Duncan Laurie181bbdd2012-06-23 16:53:57 -0700273static struct {
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700274 const u8 shift;
275 const u8 idcode;
276 struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
277} flashes[] = {
278 /* Keep it sorted by define name */
Idwer Vollering73a10182014-02-16 00:32:13 +0000279#if CONFIG_SPI_FLASH_AMIC
280 { 0, 0x37, spi_flash_probe_amic, },
281#endif
Kyösti Mälkki96d92762014-11-11 15:04:38 +0200282#if CONFIG_SPI_FLASH_ATMEL
283 { 0, 0x1f, spi_flash_probe_atmel, },
284#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700285#if CONFIG_SPI_FLASH_EON
286 { 0, 0x1c, spi_flash_probe_eon, },
287#endif
Martin Rothbceaf7f2012-09-07 15:02:35 -0600288#if CONFIG_SPI_FLASH_GIGADEVICE
289 { 0, 0xc8, spi_flash_probe_gigadevice, },
290#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700291#if CONFIG_SPI_FLASH_MACRONIX
292 { 0, 0xc2, spi_flash_probe_macronix, },
293#endif
294#if CONFIG_SPI_FLASH_SPANSION
295 { 0, 0x01, spi_flash_probe_spansion, },
296#endif
297#if CONFIG_SPI_FLASH_SST
298 { 0, 0xbf, spi_flash_probe_sst, },
299#endif
300#if CONFIG_SPI_FLASH_STMICRO
301 { 0, 0x20, spi_flash_probe_stmicro, },
302#endif
303#if CONFIG_SPI_FLASH_WINBOND
304 { 0, 0xef, spi_flash_probe_winbond, },
305#endif
306 /* Keep it sorted by best detection */
307#if CONFIG_SPI_FLASH_STMICRO
308 { 0, 0xff, spi_flash_probe_stmicro, },
309#endif
Chris Douglassb34739b2014-02-14 13:51:26 -0500310#if CONFIG_SPI_FLASH_ADESTO
311 { 0, 0x1f, spi_flash_probe_adesto, },
312#endif
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700313};
314#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
315
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800316
317/* Public API implementations. */
Gabe Black1e187352014-03-27 20:37:03 -0700318struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700319{
320 struct spi_slave *spi;
321 struct spi_flash *flash = NULL;
322 int ret, i, shift;
323 u8 idcode[IDCODE_LEN], *idp;
324
Gabe Black1e187352014-03-27 20:37:03 -0700325 spi = spi_setup_slave(bus, cs);
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700326 if (!spi) {
327 printk(BIOS_WARNING, "SF: Failed to set up slave\n");
328 return NULL;
329 }
330
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100331 if (spi->force_programmer_specific && spi->programmer_specific_probe) {
332 flash = spi->programmer_specific_probe (spi);
333 if (!flash)
334 goto err_read_id;
335 goto flash_detected;
336 }
337
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700338 /* Read the ID codes */
339 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
340 if (ret)
341 goto err_read_id;
342
343#if CONFIG_DEBUG_SPI_FLASH
David Hendricksb598bb32014-03-21 19:32:09 -0700344 printk(BIOS_SPEW, "SF: Got idcode: ");
345 for (i = 0; i < sizeof(idcode); i++)
346 printk(BIOS_SPEW, "%02x ", idcode[i]);
347 printk(BIOS_SPEW, "\n");
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700348#endif
349
350 /* count the number of continuation bytes */
351 for (shift = 0, idp = idcode;
352 shift < IDCODE_CONT_LEN && *idp == 0x7f;
353 ++shift, ++idp)
354 continue;
355
356 /* search the table for matches in shift and id */
357 for (i = 0; i < ARRAY_SIZE(flashes); ++i)
358 if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
359 /* we have a match, call probe */
360 flash = flashes[i].probe(spi, idp);
361 if (flash)
362 break;
363 }
364
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100365 if (!flash && spi->programmer_specific_probe) {
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100366 flash = spi->programmer_specific_probe (spi);
367 }
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700368 if (!flash) {
369 printk(BIOS_WARNING, "SF: Unsupported manufacturer %02x\n", *idp);
370 goto err_manufacturer_probe;
371 }
372
Vladimir Serbinenkoe23bd0e2014-01-18 17:45:32 +0100373flash_detected:
David Imhoff8d4377b2015-05-03 13:47:49 +0200374 printk(BIOS_INFO, "SF: Detected %s with sector size 0x%x, total 0x%x\n",
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700375 flash->name, flash->sector_size, flash->size);
376
Aaron Durbinc0a823c2016-08-11 14:51:38 -0500377 /*
378 * Only set the global spi_flash_dev if this is the boot
379 * device's bus and it's previously unset while in ramstage.
380 */
381 if (ENV_RAMSTAGE && IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH) &&
382 CONFIG_BOOT_DEVICE_SPI_FLASH_BUS == bus && !spi_flash_dev)
383 spi_flash_dev = flash;
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800384
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700385 return flash;
386
387err_manufacturer_probe:
388err_read_id:
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700389 return NULL;
390}
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800391
Furquan Shaikhc28984d2016-11-20 21:04:00 -0800392int spi_flash_read(const struct spi_flash *flash, u32 offset, size_t len,
393 void *buf)
394{
395 return flash->internal_read(flash, offset, len, buf);
396}
397
398int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len,
399 const void *buf)
400{
401 int ret;
402
403 if (spi_flash_volatile_group_begin(flash))
404 return -1;
405
406 ret = flash->internal_write(flash, offset, len, buf);
407
408 if (spi_flash_volatile_group_end(flash))
409 return -1;
410
411 return ret;
412}
413
414int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len)
415{
416 int ret;
417
418 if (spi_flash_volatile_group_begin(flash))
419 return -1;
420
421 ret = flash->internal_erase(flash, offset, len);
422
423 if (spi_flash_volatile_group_end(flash))
424 return -1;
425
426 return ret;
427}
428
429int spi_flash_status(const struct spi_flash *flash, u8 *reg)
430{
431 return flash->internal_status(flash, reg);
432}
433
434static uint32_t volatile_group_count CAR_GLOBAL;
435
436int spi_flash_volatile_group_begin(const struct spi_flash *flash)
437{
438 uint32_t count;
439 int ret = 0;
440
441 if (!IS_ENABLED(CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP))
442 return ret;
443
444 count = car_get_var(volatile_group_count);
445 if (count == 0)
446 ret = chipset_volatile_group_begin(flash);
447
448 count++;
449 car_set_var(volatile_group_count, count);
450 return ret;
451}
452
453int spi_flash_volatile_group_end(const struct spi_flash *flash)
454{
455 uint32_t count;
456 int ret = 0;
457
458 if (!IS_ENABLED(CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP))
459 return ret;
460
461 count = car_get_var(volatile_group_count);
462 assert(count == 0);
463 count--;
464 car_set_var(volatile_group_count, count);
465
466 if (count == 0)
467 ret = chipset_volatile_group_end(flash);
468
469 return ret;
470}
471
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800472void lb_spi_flash(struct lb_header *header)
473{
474 struct lb_spi_flash *flash;
475
Aaron Durbinc0a823c2016-08-11 14:51:38 -0500476 if (!IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
477 return;
478
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800479 flash = (struct lb_spi_flash *)lb_new_record(header);
480
481 flash->tag = LB_TAG_SPI_FLASH;
482 flash->size = sizeof(*flash);
483
484 /* Try to get the flash device if not loaded yet */
Aaron Durbin899d13d2015-05-15 23:39:23 -0500485 if (!spi_flash_dev)
486 boot_device_init();
Dan Ehrenberga5aac762015-01-08 10:29:19 -0800487
488 if (spi_flash_dev) {
489 flash->flash_size = spi_flash_dev->size;
490 flash->sector_size = spi_flash_dev->sector_size;
491 flash->erase_cmd = spi_flash_dev->erase_cmd;
492 } else {
493 flash->flash_size = CONFIG_ROM_SIZE;
494 /* Default 64k erase command should work on most flash.
495 * Uniform 4k erase only works on certain devices. */
496 flash->sector_size = 64 * KiB;
497 flash->erase_cmd = CMD_BLOCK_ERASE;
498 }
499}