blob: 7b753ad6a2a6a0446224ca0794a6aaaa9fb9819d [file] [log] [blame]
Mike Frysinger9ce7e532008-02-19 00:58:13 -05001/*
2 * SPI flash driver
3 *
4 * Enter bugs at http://blackfin.uclinux.org/
5 *
Mike Frysinger6e87ea02008-10-11 22:47:34 -04006 * Copyright (c) 2005-2008 Analog Devices Inc.
Mike Frysinger9ce7e532008-02-19 00:58:13 -05007 *
8 * Licensed under the GPL-2 or later.
9 */
10
11/* Configuration options:
12 * CONFIG_SPI_BAUD - value to load into SPI_BAUD (divisor of SCLK to get SPI CLK)
13 * CONFIG_SPI_FLASH_SLOW_READ - force usage of the slower read
14 * WARNING: make sure your SCLK + SPI_BAUD is slow enough
15 */
16
17#include <common.h>
18#include <malloc.h>
19#include <asm/io.h>
20#include <asm/mach-common/bits/spi.h>
Mike Frysingerbf1e0282008-10-11 22:51:23 -040021#include <asm/mach-common/bits/dma.h>
Mike Frysinger9ce7e532008-02-19 00:58:13 -050022
23/* Forcibly phase out these */
24#ifdef CONFIG_SPI_FLASH_NUM_SECTORS
25# error do not set CONFIG_SPI_FLASH_NUM_SECTORS
26#endif
27#ifdef CONFIG_SPI_FLASH_SECTOR_SIZE
28# error do not set CONFIG_SPI_FLASH_SECTOR_SIZE
29#endif
30
31#if defined(CONFIG_SPI)
32
33struct flash_info {
34 char *name;
35 uint16_t id;
Mike Frysinger5e8f2452008-10-11 22:51:56 -040036 uint16_t ext_id;
Mike Frysinger9ce7e532008-02-19 00:58:13 -050037 unsigned sector_size;
38 unsigned num_sectors;
39};
40
41/* SPI Speeds: 50 MHz / 33 MHz */
42static struct flash_info flash_spansion_serial_flash[] = {
Mike Frysinger5e8f2452008-10-11 22:51:56 -040043 { "S25FL016", 0x0215, 0, 64 * 1024, 32 },
44 { "S25FL032", 0x0216, 0, 64 * 1024, 64 },
45 { "S25FL064", 0x0217, 0, 64 * 1024, 128 },
46 { "S25FL128-00", 0x2018, 0x0301, 64 * 1024, 256 }, /* Package marking FL128PIF */
47 { "S25FL128-01", 0x2018, 0x0300, 128 * 1024, 64 }, /* Package marking FL128PIFL */
48 { NULL, 0, 0, 0, 0 }
Mike Frysinger9ce7e532008-02-19 00:58:13 -050049};
50
51/* SPI Speeds: 50 MHz / 20 MHz */
52static struct flash_info flash_st_serial_flash[] = {
Mike Frysinger5e8f2452008-10-11 22:51:56 -040053 { "m25p05", 0x2010, 0, 32 * 1024, 2 },
54 { "m25p10", 0x2011, 0, 32 * 1024, 4 },
55 { "m25p20", 0x2012, 0, 64 * 1024, 4 },
56 { "m25p40", 0x2013, 0, 64 * 1024, 8 },
57 { "m25p80", 0x20FF, 0, 64 * 1024, 16 },
58 { "m25p16", 0x2015, 0, 64 * 1024, 32 },
59 { "m25p32", 0x2016, 0, 64 * 1024, 64 },
60 { "m25p64", 0x2017, 0, 64 * 1024, 128 },
61 { "m25p128", 0x2018, 0, 256 * 1024, 64 },
62 { NULL, 0, 0, 0, 0 }
Mike Frysinger9ce7e532008-02-19 00:58:13 -050063};
64
Mike Frysingerefcc08c2008-10-11 22:51:05 -040065/* SPI Speeds: 20 MHz / 40 MHz */
66static struct flash_info flash_sst_serial_flash[] = {
Mike Frysinger5e8f2452008-10-11 22:51:56 -040067 { "SST25WF512", 0x2501, 0, 4 * 1024, 128 },
68 { "SST25WF010", 0x2502, 0, 4 * 1024, 256 },
69 { "SST25WF020", 0x2503, 0, 4 * 1024, 512 },
70 { "SST25WF040", 0x2504, 0, 4 * 1024, 1024 },
71 { NULL, 0, 0, 0, 0 }
Mike Frysingerefcc08c2008-10-11 22:51:05 -040072};
73
Mike Frysinger9ce7e532008-02-19 00:58:13 -050074/* SPI Speeds: 66 MHz / 33 MHz */
75static struct flash_info flash_atmel_dataflash[] = {
Mike Frysinger5e8f2452008-10-11 22:51:56 -040076 { "AT45DB011x", 0x0c, 0, 264, 512 },
77 { "AT45DB021x", 0x14, 0, 264, 1025 },
78 { "AT45DB041x", 0x1c, 0, 264, 2048 },
79 { "AT45DB081x", 0x24, 0, 264, 4096 },
80 { "AT45DB161x", 0x2c, 0, 528, 4096 },
81 { "AT45DB321x", 0x34, 0, 528, 8192 },
82 { "AT45DB642x", 0x3c, 0, 1056, 8192 },
83 { NULL, 0, 0, 0, 0 }
Mike Frysinger9ce7e532008-02-19 00:58:13 -050084};
85
86/* SPI Speed: 50 MHz / 25 MHz or 40 MHz / 20 MHz */
87static struct flash_info flash_winbond_serial_flash[] = {
Mike Frysinger5e8f2452008-10-11 22:51:56 -040088 { "W25X10", 0x3011, 0, 16 * 256, 32 },
89 { "W25X20", 0x3012, 0, 16 * 256, 64 },
90 { "W25X40", 0x3013, 0, 16 * 256, 128 },
91 { "W25X80", 0x3014, 0, 16 * 256, 256 },
92 { "W25P80", 0x2014, 0, 256 * 256, 16 },
93 { "W25P16", 0x2015, 0, 256 * 256, 32 },
94 { NULL, 0, 0, 0, 0 }
Mike Frysinger9ce7e532008-02-19 00:58:13 -050095};
96
97struct flash_ops {
98 uint8_t read, write, erase, status;
99};
100
101#ifdef CONFIG_SPI_FLASH_SLOW_READ
102# define OP_READ 0x03
103#else
104# define OP_READ 0x0B
105#endif
106static struct flash_ops flash_st_ops = {
107 .read = OP_READ,
108 .write = 0x02,
109 .erase = 0xD8,
110 .status = 0x05,
111};
112
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400113static struct flash_ops flash_sst_ops = {
114 .read = OP_READ,
115 .write = 0x02,
116 .erase = 0x20,
117 .status = 0x05,
118};
119
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500120static struct flash_ops flash_atmel_ops = {
121 .read = OP_READ,
122 .write = 0x82,
123 .erase = 0x81,
124 .status = 0xD7,
125};
126
127static struct flash_ops flash_winbond_ops = {
128 .read = OP_READ,
129 .write = 0x02,
130 .erase = 0x20,
131 .status = 0x05,
132};
133
134struct manufacturer_info {
135 const char *name;
136 uint8_t id;
137 struct flash_info *flashes;
138 struct flash_ops *ops;
139};
140
141static struct {
142 struct manufacturer_info *manufacturer;
143 struct flash_info *flash;
144 struct flash_ops *ops;
Mike Frysinger5e8f2452008-10-11 22:51:56 -0400145 uint8_t manufacturer_id, device_id1, device_id2, device_extid1, device_extid2;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500146 unsigned int write_length;
147 unsigned long sector_size, num_sectors;
148} flash;
149
150enum {
151 JED_MANU_SPANSION = 0x01,
152 JED_MANU_ST = 0x20,
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400153 JED_MANU_SST = 0xBF,
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500154 JED_MANU_ATMEL = 0x1F,
155 JED_MANU_WINBOND = 0xEF,
156};
157
158static struct manufacturer_info flash_manufacturers[] = {
159 {
160 .name = "Spansion",
161 .id = JED_MANU_SPANSION,
162 .flashes = flash_spansion_serial_flash,
163 .ops = &flash_st_ops,
164 },
165 {
166 .name = "ST",
167 .id = JED_MANU_ST,
168 .flashes = flash_st_serial_flash,
169 .ops = &flash_st_ops,
170 },
171 {
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400172 .name = "SST",
173 .id = JED_MANU_SST,
174 .flashes = flash_sst_serial_flash,
175 .ops = &flash_sst_ops,
176 },
177 {
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500178 .name = "Atmel",
179 .id = JED_MANU_ATMEL,
180 .flashes = flash_atmel_dataflash,
181 .ops = &flash_atmel_ops,
182 },
183 {
184 .name = "Winbond",
185 .id = JED_MANU_WINBOND,
186 .flashes = flash_winbond_serial_flash,
187 .ops = &flash_winbond_ops,
188 },
189};
190
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400191#define TIMEOUT 5000 /* timeout of 5 seconds */
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500192
Mike Frysinger6e87ea02008-10-11 22:47:34 -0400193/* If part has multiple SPI flashes, assume SPI0 as that is
194 * the one we can boot off of ...
195 */
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500196#ifndef pSPI_CTL
197# define pSPI_CTL pSPI0_CTL
198# define pSPI_BAUD pSPI0_BAUD
199# define pSPI_FLG pSPI0_FLG
200# define pSPI_RDBR pSPI0_RDBR
201# define pSPI_STAT pSPI0_STAT
202# define pSPI_TDBR pSPI0_TDBR
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500203#endif
204
205/* Default to the SPI SSEL that we boot off of:
206 * BF54x, BF537, (everything new?): SSEL1
Mike Frysinger6e87ea02008-10-11 22:47:34 -0400207 * BF51x, BF533, BF561: SSEL2
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500208 */
209#ifndef CONFIG_SPI_FLASH_SSEL
Mike Frysinger4b7e3d02009-01-13 11:00:29 -0500210# define CONFIG_SPI_FLASH_SSEL BFIN_BOOT_SPI_SSEL
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500211#endif
212#define SSEL_MASK (1 << CONFIG_SPI_FLASH_SSEL)
213
214static void SPI_INIT(void)
215{
216 /* [#3541] This delay appears to be necessary, but not sure
217 * exactly why as the history behind it is non-existant.
218 */
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400219 *pSPI_CTL = 0;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500220 udelay(CONFIG_CCLK_HZ / 25000000);
221
222 /* enable SPI pins: SSEL, MOSI, MISO, SCK */
223#ifdef __ADSPBF54x__
Mike Frysinger6e87ea02008-10-11 22:47:34 -0400224 *pPORTE_FER |= (PE0 | PE1 | PE2 | PE4);
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500225#elif defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__)
226 *pPORTF_FER |= (PF10 | PF11 | PF12 | PF13);
227#elif defined(__ADSPBF52x__)
228 bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_3);
229 bfin_write_PORTG_FER(bfin_read_PORTG_FER() | PG1 | PG2 | PG3 | PG4);
Mike Frysinger6e87ea02008-10-11 22:47:34 -0400230#elif defined(__ADSPBF51x__)
231 bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~PORT_x_MUX_7_MASK) | PORT_x_MUX_7_FUNC_1);
232 bfin_write_PORTG_FER(bfin_read_PORTG_FER() | PG12 | PG13 | PG14 | PG15);
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500233#endif
234
235 /* initate communication upon write of TDBR */
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400236 *pSPI_CTL = (SPE | MSTR | CPHA | CPOL | TDBR_CORE);
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500237 *pSPI_BAUD = CONFIG_SPI_BAUD;
238}
239
240static void SPI_DEINIT(void)
241{
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400242 *pSPI_CTL = 0;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500243 *pSPI_BAUD = 0;
244 SSYNC();
245}
246
247static void SPI_ON(void)
248{
249 /* toggle SSEL to reset the device so it'll take a new command */
250 *pSPI_FLG = 0xFF00 | SSEL_MASK;
251 SSYNC();
252
253 *pSPI_FLG = ((0xFF & ~SSEL_MASK) << 8) | SSEL_MASK;
254 SSYNC();
255}
256
257static void SPI_OFF(void)
258{
259 /* put SPI settings back to reset state */
260 *pSPI_FLG = 0xFF00;
261 SSYNC();
262}
263
264static uint8_t spi_write_read_byte(uint8_t transmit)
265{
266 *pSPI_TDBR = transmit;
267 SSYNC();
268
269 while ((*pSPI_STAT & TXS))
270 if (ctrlc())
271 break;
272 while (!(*pSPI_STAT & SPIF))
273 if (ctrlc())
274 break;
275 while (!(*pSPI_STAT & RXS))
276 if (ctrlc())
277 break;
278
279 /* Read dummy to empty the receive register */
280 return *pSPI_RDBR;
281}
282
283static uint8_t read_status_register(void)
284{
285 uint8_t status_register;
286
287 /* send instruction to read status register */
288 SPI_ON();
289 spi_write_read_byte(flash.ops->status);
290 /* send dummy to receive the status register */
291 status_register = spi_write_read_byte(0);
292 SPI_OFF();
293
294 return status_register;
295}
296
297static int wait_for_ready_status(void)
298{
299 ulong start = get_timer(0);
300
301 while (get_timer(0) - start < TIMEOUT) {
302 switch (flash.manufacturer_id) {
303 case JED_MANU_SPANSION:
304 case JED_MANU_ST:
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400305 case JED_MANU_SST:
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500306 case JED_MANU_WINBOND:
307 if (!(read_status_register() & 0x01))
308 return 0;
309 break;
310
311 case JED_MANU_ATMEL:
312 if (read_status_register() & 0x80)
313 return 0;
314 break;
315 }
316
317 if (ctrlc()) {
318 puts("\nAbort\n");
319 return -1;
320 }
321 }
322
323 puts("Timeout\n");
324 return -1;
325}
326
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400327static int enable_writing(void)
328{
329 ulong start;
330
331 if (flash.manufacturer_id == JED_MANU_ATMEL)
332 return 0;
333
334 /* A write enable instruction must previously have been executed */
335 SPI_ON();
336 spi_write_read_byte(0x06);
337 SPI_OFF();
338
339 /* The status register will be polled to check the write enable latch "WREN" */
340 start = get_timer(0);
341 while (get_timer(0) - start < TIMEOUT) {
342 if (read_status_register() & 0x02)
343 return 0;
344
345 if (ctrlc()) {
346 puts("\nAbort\n");
347 return -1;
348 }
349 }
350
351 puts("Timeout\n");
352 return -1;
353}
354
355static void write_status_register(uint8_t val)
356{
357 if (flash.manufacturer_id != JED_MANU_SST)
358 hang();
359
360 if (enable_writing())
361 return;
362
363 /* send instruction to write status register */
364 SPI_ON();
365 spi_write_read_byte(0x01);
366 /* and clear it! */
367 spi_write_read_byte(val);
368 SPI_OFF();
369}
370
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500371/* Request and read the manufacturer and device id of parts which
372 * are compatible with the JEDEC standard (JEP106) and use that to
373 * setup other operating conditions.
374 */
375static int spi_detect_part(void)
376{
Mike Frysinger5e8f2452008-10-11 22:51:56 -0400377 uint16_t dev_id, dev_extid;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500378 size_t i;
379
380 static char called_init;
381 if (called_init)
382 return 0;
383
Mike Frysinger5b8cfbe2008-10-11 22:50:10 -0400384#ifdef CONFIG_SPI_FLASH_M25P80
385 flash.manufacturer_id = JED_MANU_ST;
386 flash.device_id1 = 0x20;
387 flash.device_id2 = 0xFF;
388#else
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500389 SPI_ON();
390
391 /* Send the request for the part identification */
392 spi_write_read_byte(0x9F);
393
394 /* Now read in the manufacturer id bytes */
395 do {
396 flash.manufacturer_id = spi_write_read_byte(0);
397 if (flash.manufacturer_id == 0x7F)
398 puts("Warning: unhandled manufacturer continuation byte!\n");
399 } while (flash.manufacturer_id == 0x7F);
400
401 /* Now read in the first device id byte */
402 flash.device_id1 = spi_write_read_byte(0);
403
404 /* Now read in the second device id byte */
405 flash.device_id2 = spi_write_read_byte(0);
406
Mike Frysinger5e8f2452008-10-11 22:51:56 -0400407 /* Read extended device ids */
408 flash.device_extid1 = spi_write_read_byte(0);
409 flash.device_extid2 = spi_write_read_byte(0);
410
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500411 SPI_OFF();
Mike Frysinger5b8cfbe2008-10-11 22:50:10 -0400412#endif
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500413
414 dev_id = (flash.device_id1 << 8) | flash.device_id2;
Mike Frysinger5e8f2452008-10-11 22:51:56 -0400415 dev_extid = (flash.device_extid1 << 8) | flash.device_extid2;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500416
417 for (i = 0; i < ARRAY_SIZE(flash_manufacturers); ++i) {
418 if (flash.manufacturer_id == flash_manufacturers[i].id)
419 break;
420 }
421 if (i == ARRAY_SIZE(flash_manufacturers))
422 goto unknown;
423
424 flash.manufacturer = &flash_manufacturers[i];
425 flash.ops = flash_manufacturers[i].ops;
426
427 switch (flash.manufacturer_id) {
428 case JED_MANU_SPANSION:
429 case JED_MANU_ST:
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400430 case JED_MANU_SST:
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500431 case JED_MANU_WINBOND:
432 for (i = 0; flash.manufacturer->flashes[i].name; ++i) {
Mike Frysinger5e8f2452008-10-11 22:51:56 -0400433 if (dev_id == flash.manufacturer->flashes[i].id &&
434 (flash.manufacturer->flashes[i].ext_id == 0 ||
435 flash.manufacturer->flashes[i].ext_id == dev_extid))
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500436 break;
437 }
438 if (!flash.manufacturer->flashes[i].name)
439 goto unknown;
440
441 flash.flash = &flash.manufacturer->flashes[i];
442 flash.sector_size = flash.flash->sector_size;
443 flash.num_sectors = flash.flash->num_sectors;
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400444
445 if (flash.manufacturer_id == JED_MANU_SST)
446 flash.write_length = 1; /* pwnt :( */
447 else
448 flash.write_length = 256;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500449 break;
450
451 case JED_MANU_ATMEL: {
452 uint8_t status = read_status_register();
453
454 for (i = 0; flash.manufacturer->flashes[i].name; ++i) {
455 if ((status & 0x3c) == flash.manufacturer->flashes[i].id)
456 break;
457 }
458 if (!flash.manufacturer->flashes[i].name)
459 goto unknown;
460
461 flash.flash = &flash.manufacturer->flashes[i];
462 flash.sector_size = flash.flash->sector_size;
463 flash.num_sectors = flash.flash->num_sectors;
464
465 /* see if flash is in "power of 2" mode */
466 if (status & 0x1)
467 flash.sector_size &= ~(1 << (ffs(flash.sector_size) - 1));
468
469 flash.write_length = flash.sector_size;
470 break;
471 }
472 }
473
Mike Frysingerefcc08c2008-10-11 22:51:05 -0400474 /* the SST parts power up with software protection enabled by default */
475 if (flash.manufacturer_id == JED_MANU_SST)
476 write_status_register(0);
477
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500478 called_init = 1;
479 return 0;
480
481 unknown:
482 printf("Unknown SPI device: 0x%02X 0x%02X 0x%02X\n",
483 flash.manufacturer_id, flash.device_id1, flash.device_id2);
484 return 1;
485}
486
487/*
488 * Function: spi_init_f
489 * Description: Init SPI-Controller (ROM part)
490 * return: ---
491 */
492void spi_init_f(void)
493{
494}
495
496/*
497 * Function: spi_init_r
498 * Description: Init SPI-Controller (RAM part) -
499 * The malloc engine is ready and we can move our buffers to
500 * normal RAM
501 * return: ---
502 */
503void spi_init_r(void)
504{
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200505#if defined(CONFIG_POST) && (CONFIG_POST & CONFIG_SYS_POST_SPI)
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500506 /* Our testing strategy here is pretty basic:
507 * - fill src memory with an 8-bit pattern
508 * - write the src memory to the SPI flash
509 * - read the SPI flash into the dst memory
510 * - compare src and dst memory regions
511 * - repeat a few times
512 * The variations we test for:
513 * - change the 8-bit pattern a bit
514 * - change the read/write block size so we know:
515 * - writes smaller/equal/larger than the buffer work
516 * - writes smaller/equal/larger than the sector work
517 * - change the SPI offsets so we know:
518 * - writing partial sectors works
519 */
520 uint8_t *mem_src, *mem_dst;
521 size_t i, c, l, o;
522 size_t test_count, errors;
523 uint8_t pattern;
524
525 SPI_INIT();
526
527 if (spi_detect_part())
528 goto out;
529 eeprom_info();
530
531 ulong lengths[] = {
532 flash.write_length,
533 flash.write_length * 2,
534 flash.write_length / 2,
535 flash.sector_size,
536 flash.sector_size * 2,
537 flash.sector_size / 2
538 };
539 ulong offsets[] = {
540 0,
541 flash.write_length,
542 flash.write_length * 2,
543 flash.write_length / 2,
544 flash.write_length / 4,
545 flash.sector_size,
546 flash.sector_size * 2,
547 flash.sector_size / 2,
548 flash.sector_size / 4,
549 };
550
551 /* the exact addresses are arbitrary ... they just need to not overlap */
552 mem_src = (void *)(0);
553 mem_dst = (void *)(max(flash.write_length, flash.sector_size) * 2);
554
555 test_count = 0;
556 errors = 0;
557 pattern = 0x00;
558
559 for (i = 0; i < 16; ++i) { /* 16 = 8 bits * 2 iterations */
560 for (l = 0; l < ARRAY_SIZE(lengths); ++l) {
561 for (o = 0; o < ARRAY_SIZE(offsets); ++o) {
562 ulong len = lengths[l];
563 ulong off = offsets[o];
564
565 printf("Testing pattern 0x%02X of length %5lu and offset %5lu: ", pattern, len, off);
566
567 /* setup the source memory region */
568 memset(mem_src, pattern, len);
569
570 test_count += 4;
571 for (c = 0; c < 4; ++c) { /* 4 is just a random repeat count */
572 if (ctrlc()) {
573 puts("\nAbort\n");
574 goto out;
575 }
576
577 /* make sure background fill pattern != pattern */
578 memset(mem_dst, pattern ^ 0xFF, len);
579
580 /* write out the source memory and then read it back and compare */
581 eeprom_write(0, off, mem_src, len);
582 eeprom_read(0, off, mem_dst, len);
583
584 if (memcmp(mem_src, mem_dst, len)) {
585 for (c = 0; c < len; ++c)
586 if (mem_src[c] != mem_dst[c])
587 break;
588 printf(" FAIL @ offset %u, skipping repeats ", c);
589 ++errors;
590 break;
591 }
592
593 /* XXX: should shrink write region here to test with
594 * leading/trailing canaries so we know surrounding
595 * bytes don't get screwed.
596 */
597 }
598 puts("\n");
599 }
600 }
601
602 /* invert the pattern every other run and shift out bits slowly */
603 pattern ^= 0xFF;
604 if (i % 2)
605 pattern = (pattern | 0x01) << 1;
606 }
607
608 if (errors)
609 printf("SPI FAIL: Out of %i tests, there were %i errors ;(\n", test_count, errors);
610 else
611 printf("SPI PASS: %i tests worked!\n", test_count);
612
613 out:
614 SPI_DEINIT();
615
616#endif
617}
618
619static void transmit_address(uint32_t addr)
620{
621 /* Send the highest byte of the 24 bit address at first */
622 spi_write_read_byte(addr >> 16);
623 /* Send the middle byte of the 24 bit address at second */
624 spi_write_read_byte(addr >> 8);
625 /* Send the lowest byte of the 24 bit address finally */
626 spi_write_read_byte(addr);
627}
628
629/*
630 * Read a value from flash for verify purpose
631 * Inputs: unsigned long ulStart - holds the SPI start address
632 * int pnData - pointer to store value read from flash
633 * long lCount - number of elements to read
634 */
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400635#ifdef CONFIG_SPI_READFLASH_NODMA
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500636static int read_flash(unsigned long address, long count, uchar *buffer)
637{
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400638 size_t i, j;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500639
640 /* Send the read command to SPI device */
641 SPI_ON();
642 spi_write_read_byte(flash.ops->read);
643 transmit_address(address);
644
645#ifndef CONFIG_SPI_FLASH_SLOW_READ
646 /* Send dummy byte when doing SPI fast reads */
647 spi_write_read_byte(0);
648#endif
649
650 /* After the SPI device address has been placed on the MOSI pin the data can be */
651 /* received on the MISO pin. */
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400652 j = flash.sector_size << 1;
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500653 for (i = 1; i <= count; ++i) {
654 *buffer++ = spi_write_read_byte(0);
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400655 if (!j--) {
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500656 puts(".");
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400657 j = flash.sector_size;
658 }
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500659 }
660
661 SPI_OFF();
662
663 return 0;
664}
Mike Frysingerbf1e0282008-10-11 22:51:23 -0400665#else
666
667#ifdef __ADSPBF54x__
668#define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA4_IRQ_STATUS
669#define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA4_IRQ_STATUS
670#define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA4_CURR_DESC_PTR
671#define bfin_write_DMA_SPI_CONFIG bfin_write_DMA4_CONFIG
672#elif defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__) || \
673 defined(__ADSPBF538__) || defined(__ADSPBF539__)
674#define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA5_IRQ_STATUS
675#define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA5_IRQ_STATUS
676#define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA5_CURR_DESC_PTR
677#define bfin_write_DMA_SPI_CONFIG bfin_write_DMA5_CONFIG
678#elif defined(__ADSPBF561__)
679#define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA16_IRQ_STATUS
680#define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA16_IRQ_STATUS
681#define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA16_CURR_DESC_PTR
682#define bfin_write_DMA_SPI_CONFIG bfin_write_DMA16_CONFIG
683#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) || \
684 defined(__ADSPBF52x__) || defined(__ADSPBF51x__)
685#define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA7_IRQ_STATUS
686#define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA7_IRQ_STATUS
687#define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA7_CURR_DESC_PTR
688#define bfin_write_DMA_SPI_CONFIG bfin_write_DMA7_CONFIG
689#else
690#error "Please provide SPI DMA channel defines"
691#endif
692
693struct dmadesc_array {
694 unsigned long start_addr;
695 unsigned short cfg;
696 unsigned short x_count;
697 short x_modify;
698 unsigned short y_count;
699 short y_modify;
700} __attribute__((packed));
701
702/*
703 * Read a value from flash for verify purpose
704 * Inputs: unsigned long ulStart - holds the SPI start address
705 * int pnData - pointer to store value read from flash
706 * long lCount - number of elements to read
707 */
708
709static int read_flash(unsigned long address, long count, uchar *buffer)
710{
711 unsigned int ndsize;
712 struct dmadesc_array dma[2];
713 /* Send the read command to SPI device */
714
715 if (!count)
716 return 0;
717
718 dma[0].start_addr = (unsigned long)buffer;
719 dma[0].x_modify = 1;
720 if (count <= 65536) {
721 blackfin_dcache_flush_invalidate_range(buffer, buffer + count);
722 ndsize = NDSIZE_5;
723 dma[0].cfg = NDSIZE_0 | WNR | WDSIZE_8 | FLOW_STOP | DMAEN | DI_EN;
724 dma[0].x_count = count;
725 } else {
726 blackfin_dcache_flush_invalidate_range(buffer, buffer + 65536 - 1);
727 ndsize = NDSIZE_7;
728 dma[0].cfg = NDSIZE_5 | WNR | WDSIZE_8 | FLOW_ARRAY | DMAEN | DMA2D;
729 dma[0].x_count = 0; /* 2^16 */
730 dma[0].y_count = count >> 16; /* count / 2^16 */
731 dma[0].y_modify = 1;
732 dma[1].start_addr = (unsigned long)(buffer + (count & ~0xFFFF));
733 dma[1].cfg = NDSIZE_0 | WNR | WDSIZE_8 | FLOW_STOP | DMAEN | DI_EN;
734 dma[1].x_count = count & 0xFFFF; /* count % 2^16 */
735 dma[1].x_modify = 1;
736 }
737
738 bfin_write_DMA_SPI_CONFIG(0);
739 bfin_write_DMA_SPI_IRQ_STATUS(DMA_DONE | DMA_ERR);
740 bfin_write_DMA_SPI_CURR_DESC_PTR(dma);
741
742 SPI_ON();
743
744 spi_write_read_byte(flash.ops->read);
745 transmit_address(address);
746
747#ifndef CONFIG_SPI_FLASH_SLOW_READ
748 /* Send dummy byte when doing SPI fast reads */
749 spi_write_read_byte(0);
750#endif
751
752 bfin_write_DMA_SPI_CONFIG(ndsize | FLOW_ARRAY | DMAEN);
753 *pSPI_CTL = (MSTR | CPHA | CPOL | RDBR_DMA | SPE | SZ);
754 SSYNC();
755
756 /*
757 * We already invalidated the first 64k,
758 * now while we just wait invalidate the remaining part.
759 * Its not likely that the DMA is going to overtake
760 */
761 if (count > 65536)
762 blackfin_dcache_flush_invalidate_range(buffer + 65536,
763 buffer + count);
764
765 while (!(bfin_read_DMA_SPI_IRQ_STATUS() & DMA_DONE))
766 if (ctrlc())
767 break;
768
769 SPI_OFF();
770
771 *pSPI_CTL = 0;
772
773 bfin_write_DMA_SPI_CONFIG(0);
774
775 *pSPI_CTL = (SPE | MSTR | CPHA | CPOL | TDBR_CORE);
776
777 return 0;
778}
779#endif
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500780
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500781static long address_to_sector(unsigned long address)
782{
783 if (address > (flash.num_sectors * flash.sector_size) - 1)
784 return -1;
785 return address / flash.sector_size;
786}
787
788static int erase_sector(int address)
789{
790 /* sector gets checked in higher function, so assume it's valid
791 * here and figure out the offset of the sector in flash
792 */
793 if (enable_writing())
794 return -1;
795
796 /*
797 * Send the erase block command to the flash followed by the 24 address
798 * to point to the start of a sector
799 */
800 SPI_ON();
801 spi_write_read_byte(flash.ops->erase);
802 transmit_address(address);
803 SPI_OFF();
804
805 return wait_for_ready_status();
806}
807
808/* Write [count] bytes out of [buffer] into the given SPI [address] */
809static long write_flash(unsigned long address, long count, uchar *buffer)
810{
811 long i, write_buffer_size;
812
813 if (enable_writing())
814 return -1;
815
816 /* Send write command followed by the 24 bit address */
817 SPI_ON();
818 spi_write_read_byte(flash.ops->write);
819 transmit_address(address);
820
821 /* Shoot out a single write buffer */
822 write_buffer_size = min(count, flash.write_length);
823 for (i = 0; i < write_buffer_size; ++i)
824 spi_write_read_byte(buffer[i]);
825
826 SPI_OFF();
827
828 /* Wait for the flash to do its thing */
829 if (wait_for_ready_status()) {
830 puts("SPI Program Time out! ");
831 return -1;
832 }
833
834 return i;
835}
836
837/* Write [count] bytes out of [buffer] into the given SPI [address] */
838static int write_sector(unsigned long address, long count, uchar *buffer)
839{
840 long write_cnt;
841
842 while (count != 0) {
843 write_cnt = write_flash(address, count, buffer);
844 if (write_cnt == -1)
845 return -1;
846
847 /* Now that we've sent some bytes out to the flash, update
848 * our counters a bit
849 */
850 count -= write_cnt;
851 address += write_cnt;
852 buffer += write_cnt;
853 }
854
855 /* return the appropriate error code */
856 return 0;
857}
858
859/*
860 * Function: spi_write
861 */
862ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len)
863{
864 unsigned long offset;
865 int start_sector, end_sector;
866 int start_byte, end_byte;
867 uchar *temp = NULL;
868 int num, ret = 0;
869
870 SPI_INIT();
871
872 if (spi_detect_part())
873 goto out;
874
875 offset = addr[0] << 16 | addr[1] << 8 | addr[2];
876
877 /* Get the start block number */
878 start_sector = address_to_sector(offset);
879 if (start_sector == -1) {
880 puts("Invalid sector! ");
881 goto out;
882 }
883 end_sector = address_to_sector(offset + len - 1);
884 if (end_sector == -1) {
885 puts("Invalid sector! ");
886 goto out;
887 }
888
889 /* Since flashes operate in sector units but the eeprom command
890 * operates as a continuous stream of bytes, we need to emulate
891 * the eeprom behavior. So here we read in the sector, overlay
892 * any bytes we're actually modifying, erase the sector, and
893 * then write back out the new sector.
894 */
895 temp = malloc(flash.sector_size);
896 if (!temp) {
897 puts("Malloc for sector failed! ");
898 goto out;
899 }
900
901 for (num = start_sector; num <= end_sector; num++) {
902 unsigned long address = num * flash.sector_size;
903
904 /* XXX: should add an optimization when spanning sectors:
905 * No point in reading in a sector if we're going to be
906 * clobbering the whole thing. Need to also add a test
907 * case to make sure the optimization is correct.
908 */
909 if (read_flash(address, flash.sector_size, temp)) {
910 puts("Read sector failed! ");
911 len = 0;
912 break;
913 }
914
915 start_byte = max(address, offset);
916 end_byte = address + flash.sector_size - 1;
917 if (end_byte > (offset + len))
918 end_byte = (offset + len - 1);
919
920 memcpy(temp + start_byte - address,
921 buffer + start_byte - offset,
922 end_byte - start_byte + 1);
923
924 if (erase_sector(address)) {
925 puts("Erase sector failed! ");
926 goto out;
927 }
928
929 if (write_sector(address, flash.sector_size, temp)) {
930 puts("Write sector failed! ");
931 goto out;
932 }
933
934 puts(".");
935 }
936
937 ret = len;
938
939 out:
940 free(temp);
941
942 SPI_DEINIT();
943
944 return ret;
945}
946
947/*
948 * Function: spi_read
949 */
950ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len)
951{
952 unsigned long offset;
953
954 SPI_INIT();
955
956 if (spi_detect_part())
957 len = 0;
958 else {
959 offset = addr[0] << 16 | addr[1] << 8 | addr[2];
960 read_flash(offset, len, buffer);
961 }
962
963 SPI_DEINIT();
964
965 return len;
966}
967
968/*
969 * Spit out some useful information about the SPI eeprom
970 */
971int eeprom_info(void)
972{
973 int ret = 0;
974
975 SPI_INIT();
976
977 if (spi_detect_part())
978 ret = 1;
979 else
980 printf("SPI Device: %s 0x%02X (%s) 0x%02X 0x%02X\n"
Mike Frysingerfe033ad2008-10-12 06:02:55 -0400981 "Parameters: num sectors = %lu, sector size = %lu, write size = %i\n"
982 "Flash Size: %lu mbit (%lu mbyte)\n"
Mike Frysinger9ce7e532008-02-19 00:58:13 -0500983 "Status: 0x%02X\n",
984 flash.flash->name, flash.manufacturer_id, flash.manufacturer->name,
985 flash.device_id1, flash.device_id2, flash.num_sectors,
986 flash.sector_size, flash.write_length,
987 (flash.num_sectors * flash.sector_size) >> 17,
988 (flash.num_sectors * flash.sector_size) >> 20,
989 read_status_register());
990
991 SPI_DEINIT();
992
993 return ret;
994}
995
996#endif