4 * Enter bugs at http://blackfin.uclinux.org/
6 * Copyright (c) 2005-2008 Analog Devices Inc.
8 * Licensed under the GPL-2 or later.
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
20 #include <asm/mach-common/bits/spi.h>
21 #include <asm/mach-common/bits/dma.h>
23 /* Forcibly phase out these */
24 #ifdef CONFIG_SPI_FLASH_NUM_SECTORS
25 # error do not set CONFIG_SPI_FLASH_NUM_SECTORS
27 #ifdef CONFIG_SPI_FLASH_SECTOR_SIZE
28 # error do not set CONFIG_SPI_FLASH_SECTOR_SIZE
31 #if defined(CONFIG_SPI)
40 /* SPI Speeds: 50 MHz / 33 MHz */
41 static struct flash_info flash_spansion_serial_flash[] = {
42 { "S25FL016", 0x0215, 64 * 1024, 32 },
43 { "S25FL032", 0x0216, 64 * 1024, 64 },
44 { "S25FL064", 0x0217, 64 * 1024, 128 },
45 { "S25FL0128", 0x0218, 256 * 1024, 64 },
49 /* SPI Speeds: 50 MHz / 20 MHz */
50 static struct flash_info flash_st_serial_flash[] = {
51 { "m25p05", 0x2010, 32 * 1024, 2 },
52 { "m25p10", 0x2011, 32 * 1024, 4 },
53 { "m25p20", 0x2012, 64 * 1024, 4 },
54 { "m25p40", 0x2013, 64 * 1024, 8 },
55 { "m25p80", 0x20FF, 64 * 1024, 16 },
56 { "m25p16", 0x2015, 64 * 1024, 32 },
57 { "m25p32", 0x2016, 64 * 1024, 64 },
58 { "m25p64", 0x2017, 64 * 1024, 128 },
59 { "m25p128", 0x2018, 256 * 1024, 64 },
63 /* SPI Speeds: 20 MHz / 40 MHz */
64 static struct flash_info flash_sst_serial_flash[] = {
65 { "SST25WF512", 0x2501, 4 * 1024, 128 },
66 { "SST25WF010", 0x2502, 4 * 1024, 256 },
67 { "SST25WF020", 0x2503, 4 * 1024, 512 },
68 { "SST25WF040", 0x2504, 4 * 1024, 1024 },
72 /* SPI Speeds: 66 MHz / 33 MHz */
73 static struct flash_info flash_atmel_dataflash[] = {
74 { "AT45DB011x", 0x0c, 264, 512 },
75 { "AT45DB021x", 0x14, 264, 1025 },
76 { "AT45DB041x", 0x1c, 264, 2048 },
77 { "AT45DB081x", 0x24, 264, 4096 },
78 { "AT45DB161x", 0x2c, 528, 4096 },
79 { "AT45DB321x", 0x34, 528, 8192 },
80 { "AT45DB642x", 0x3c, 1056, 8192 },
84 /* SPI Speed: 50 MHz / 25 MHz or 40 MHz / 20 MHz */
85 static struct flash_info flash_winbond_serial_flash[] = {
86 { "W25X10", 0x3011, 16 * 256, 32 },
87 { "W25X20", 0x3012, 16 * 256, 64 },
88 { "W25X40", 0x3013, 16 * 256, 128 },
89 { "W25X80", 0x3014, 16 * 256, 256 },
90 { "W25P80", 0x2014, 256 * 256, 16 },
91 { "W25P16", 0x2015, 256 * 256, 32 },
96 uint8_t read, write, erase, status;
99 #ifdef CONFIG_SPI_FLASH_SLOW_READ
100 # define OP_READ 0x03
102 # define OP_READ 0x0B
104 static struct flash_ops flash_st_ops = {
111 static struct flash_ops flash_sst_ops = {
118 static struct flash_ops flash_atmel_ops = {
125 static struct flash_ops flash_winbond_ops = {
132 struct manufacturer_info {
135 struct flash_info *flashes;
136 struct flash_ops *ops;
140 struct manufacturer_info *manufacturer;
141 struct flash_info *flash;
142 struct flash_ops *ops;
143 uint8_t manufacturer_id, device_id1, device_id2;
144 unsigned int write_length;
145 unsigned long sector_size, num_sectors;
149 JED_MANU_SPANSION = 0x01,
152 JED_MANU_ATMEL = 0x1F,
153 JED_MANU_WINBOND = 0xEF,
156 static struct manufacturer_info flash_manufacturers[] = {
159 .id = JED_MANU_SPANSION,
160 .flashes = flash_spansion_serial_flash,
161 .ops = &flash_st_ops,
166 .flashes = flash_st_serial_flash,
167 .ops = &flash_st_ops,
172 .flashes = flash_sst_serial_flash,
173 .ops = &flash_sst_ops,
177 .id = JED_MANU_ATMEL,
178 .flashes = flash_atmel_dataflash,
179 .ops = &flash_atmel_ops,
183 .id = JED_MANU_WINBOND,
184 .flashes = flash_winbond_serial_flash,
185 .ops = &flash_winbond_ops,
189 #define TIMEOUT 5000 /* timeout of 5 seconds */
191 /* If part has multiple SPI flashes, assume SPI0 as that is
192 * the one we can boot off of ...
195 # define pSPI_CTL pSPI0_CTL
196 # define pSPI_BAUD pSPI0_BAUD
197 # define pSPI_FLG pSPI0_FLG
198 # define pSPI_RDBR pSPI0_RDBR
199 # define pSPI_STAT pSPI0_STAT
200 # define pSPI_TDBR pSPI0_TDBR
203 /* Default to the SPI SSEL that we boot off of:
204 * BF54x, BF537, (everything new?): SSEL1
205 * BF51x, BF533, BF561: SSEL2
207 #ifndef CONFIG_SPI_FLASH_SSEL
208 # define CONFIG_SPI_FLASH_SSEL BFIN_BOOT_SPI_SSEL
210 #define SSEL_MASK (1 << CONFIG_SPI_FLASH_SSEL)
212 static void SPI_INIT(void)
214 /* [#3541] This delay appears to be necessary, but not sure
215 * exactly why as the history behind it is non-existant.
218 udelay(CONFIG_CCLK_HZ / 25000000);
220 /* enable SPI pins: SSEL, MOSI, MISO, SCK */
222 *pPORTE_FER |= (PE0 | PE1 | PE2 | PE4);
223 #elif defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__)
224 *pPORTF_FER |= (PF10 | PF11 | PF12 | PF13);
225 #elif defined(__ADSPBF52x__)
226 bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_3);
227 bfin_write_PORTG_FER(bfin_read_PORTG_FER() | PG1 | PG2 | PG3 | PG4);
228 #elif defined(__ADSPBF51x__)
229 bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~PORT_x_MUX_7_MASK) | PORT_x_MUX_7_FUNC_1);
230 bfin_write_PORTG_FER(bfin_read_PORTG_FER() | PG12 | PG13 | PG14 | PG15);
233 /* initate communication upon write of TDBR */
234 *pSPI_CTL = (SPE | MSTR | CPHA | CPOL | TDBR_CORE);
235 *pSPI_BAUD = CONFIG_SPI_BAUD;
238 static void SPI_DEINIT(void)
245 static void SPI_ON(void)
247 /* toggle SSEL to reset the device so it'll take a new command */
248 *pSPI_FLG = 0xFF00 | SSEL_MASK;
251 *pSPI_FLG = ((0xFF & ~SSEL_MASK) << 8) | SSEL_MASK;
255 static void SPI_OFF(void)
257 /* put SPI settings back to reset state */
262 static uint8_t spi_write_read_byte(uint8_t transmit)
264 *pSPI_TDBR = transmit;
267 while ((*pSPI_STAT & TXS))
270 while (!(*pSPI_STAT & SPIF))
273 while (!(*pSPI_STAT & RXS))
277 /* Read dummy to empty the receive register */
281 static uint8_t read_status_register(void)
283 uint8_t status_register;
285 /* send instruction to read status register */
287 spi_write_read_byte(flash.ops->status);
288 /* send dummy to receive the status register */
289 status_register = spi_write_read_byte(0);
292 return status_register;
295 static int wait_for_ready_status(void)
297 ulong start = get_timer(0);
299 while (get_timer(0) - start < TIMEOUT) {
300 switch (flash.manufacturer_id) {
301 case JED_MANU_SPANSION:
304 case JED_MANU_WINBOND:
305 if (!(read_status_register() & 0x01))
310 if (read_status_register() & 0x80)
325 static int enable_writing(void)
329 if (flash.manufacturer_id == JED_MANU_ATMEL)
332 /* A write enable instruction must previously have been executed */
334 spi_write_read_byte(0x06);
337 /* The status register will be polled to check the write enable latch "WREN" */
338 start = get_timer(0);
339 while (get_timer(0) - start < TIMEOUT) {
340 if (read_status_register() & 0x02)
353 static void write_status_register(uint8_t val)
355 if (flash.manufacturer_id != JED_MANU_SST)
358 if (enable_writing())
361 /* send instruction to write status register */
363 spi_write_read_byte(0x01);
365 spi_write_read_byte(val);
369 /* Request and read the manufacturer and device id of parts which
370 * are compatible with the JEDEC standard (JEP106) and use that to
371 * setup other operating conditions.
373 static int spi_detect_part(void)
378 static char called_init;
382 #ifdef CONFIG_SPI_FLASH_M25P80
383 flash.manufacturer_id = JED_MANU_ST;
384 flash.device_id1 = 0x20;
385 flash.device_id2 = 0xFF;
389 /* Send the request for the part identification */
390 spi_write_read_byte(0x9F);
392 /* Now read in the manufacturer id bytes */
394 flash.manufacturer_id = spi_write_read_byte(0);
395 if (flash.manufacturer_id == 0x7F)
396 puts("Warning: unhandled manufacturer continuation byte!\n");
397 } while (flash.manufacturer_id == 0x7F);
399 /* Now read in the first device id byte */
400 flash.device_id1 = spi_write_read_byte(0);
402 /* Now read in the second device id byte */
403 flash.device_id2 = spi_write_read_byte(0);
408 dev_id = (flash.device_id1 << 8) | flash.device_id2;
410 for (i = 0; i < ARRAY_SIZE(flash_manufacturers); ++i) {
411 if (flash.manufacturer_id == flash_manufacturers[i].id)
414 if (i == ARRAY_SIZE(flash_manufacturers))
417 flash.manufacturer = &flash_manufacturers[i];
418 flash.ops = flash_manufacturers[i].ops;
420 switch (flash.manufacturer_id) {
421 case JED_MANU_SPANSION:
424 case JED_MANU_WINBOND:
425 for (i = 0; flash.manufacturer->flashes[i].name; ++i) {
426 if (dev_id == flash.manufacturer->flashes[i].id)
429 if (!flash.manufacturer->flashes[i].name)
432 flash.flash = &flash.manufacturer->flashes[i];
433 flash.sector_size = flash.flash->sector_size;
434 flash.num_sectors = flash.flash->num_sectors;
436 if (flash.manufacturer_id == JED_MANU_SST)
437 flash.write_length = 1; /* pwnt :( */
439 flash.write_length = 256;
442 case JED_MANU_ATMEL: {
443 uint8_t status = read_status_register();
445 for (i = 0; flash.manufacturer->flashes[i].name; ++i) {
446 if ((status & 0x3c) == flash.manufacturer->flashes[i].id)
449 if (!flash.manufacturer->flashes[i].name)
452 flash.flash = &flash.manufacturer->flashes[i];
453 flash.sector_size = flash.flash->sector_size;
454 flash.num_sectors = flash.flash->num_sectors;
456 /* see if flash is in "power of 2" mode */
458 flash.sector_size &= ~(1 << (ffs(flash.sector_size) - 1));
460 flash.write_length = flash.sector_size;
465 /* the SST parts power up with software protection enabled by default */
466 if (flash.manufacturer_id == JED_MANU_SST)
467 write_status_register(0);
473 printf("Unknown SPI device: 0x%02X 0x%02X 0x%02X\n",
474 flash.manufacturer_id, flash.device_id1, flash.device_id2);
479 * Function: spi_init_f
480 * Description: Init SPI-Controller (ROM part)
483 void spi_init_f(void)
488 * Function: spi_init_r
489 * Description: Init SPI-Controller (RAM part) -
490 * The malloc engine is ready and we can move our buffers to
494 void spi_init_r(void)
496 #if defined(CONFIG_POST) && (CONFIG_POST & CONFIG_SYS_POST_SPI)
497 /* Our testing strategy here is pretty basic:
498 * - fill src memory with an 8-bit pattern
499 * - write the src memory to the SPI flash
500 * - read the SPI flash into the dst memory
501 * - compare src and dst memory regions
502 * - repeat a few times
503 * The variations we test for:
504 * - change the 8-bit pattern a bit
505 * - change the read/write block size so we know:
506 * - writes smaller/equal/larger than the buffer work
507 * - writes smaller/equal/larger than the sector work
508 * - change the SPI offsets so we know:
509 * - writing partial sectors works
511 uint8_t *mem_src, *mem_dst;
513 size_t test_count, errors;
518 if (spi_detect_part())
524 flash.write_length * 2,
525 flash.write_length / 2,
527 flash.sector_size * 2,
528 flash.sector_size / 2
533 flash.write_length * 2,
534 flash.write_length / 2,
535 flash.write_length / 4,
537 flash.sector_size * 2,
538 flash.sector_size / 2,
539 flash.sector_size / 4,
542 /* the exact addresses are arbitrary ... they just need to not overlap */
543 mem_src = (void *)(0);
544 mem_dst = (void *)(max(flash.write_length, flash.sector_size) * 2);
550 for (i = 0; i < 16; ++i) { /* 16 = 8 bits * 2 iterations */
551 for (l = 0; l < ARRAY_SIZE(lengths); ++l) {
552 for (o = 0; o < ARRAY_SIZE(offsets); ++o) {
553 ulong len = lengths[l];
554 ulong off = offsets[o];
556 printf("Testing pattern 0x%02X of length %5lu and offset %5lu: ", pattern, len, off);
558 /* setup the source memory region */
559 memset(mem_src, pattern, len);
562 for (c = 0; c < 4; ++c) { /* 4 is just a random repeat count */
568 /* make sure background fill pattern != pattern */
569 memset(mem_dst, pattern ^ 0xFF, len);
571 /* write out the source memory and then read it back and compare */
572 eeprom_write(0, off, mem_src, len);
573 eeprom_read(0, off, mem_dst, len);
575 if (memcmp(mem_src, mem_dst, len)) {
576 for (c = 0; c < len; ++c)
577 if (mem_src[c] != mem_dst[c])
579 printf(" FAIL @ offset %u, skipping repeats ", c);
584 /* XXX: should shrink write region here to test with
585 * leading/trailing canaries so we know surrounding
586 * bytes don't get screwed.
593 /* invert the pattern every other run and shift out bits slowly */
596 pattern = (pattern | 0x01) << 1;
600 printf("SPI FAIL: Out of %i tests, there were %i errors ;(\n", test_count, errors);
602 printf("SPI PASS: %i tests worked!\n", test_count);
610 static void transmit_address(uint32_t addr)
612 /* Send the highest byte of the 24 bit address at first */
613 spi_write_read_byte(addr >> 16);
614 /* Send the middle byte of the 24 bit address at second */
615 spi_write_read_byte(addr >> 8);
616 /* Send the lowest byte of the 24 bit address finally */
617 spi_write_read_byte(addr);
621 * Read a value from flash for verify purpose
622 * Inputs: unsigned long ulStart - holds the SPI start address
623 * int pnData - pointer to store value read from flash
624 * long lCount - number of elements to read
626 #ifdef CONFIG_SPI_READFLASH_NODMA
627 static int read_flash(unsigned long address, long count, uchar *buffer)
631 /* Send the read command to SPI device */
633 spi_write_read_byte(flash.ops->read);
634 transmit_address(address);
636 #ifndef CONFIG_SPI_FLASH_SLOW_READ
637 /* Send dummy byte when doing SPI fast reads */
638 spi_write_read_byte(0);
641 /* After the SPI device address has been placed on the MOSI pin the data can be */
642 /* received on the MISO pin. */
643 j = flash.sector_size << 1;
644 for (i = 1; i <= count; ++i) {
645 *buffer++ = spi_write_read_byte(0);
648 j = flash.sector_size;
659 #define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA4_IRQ_STATUS
660 #define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA4_IRQ_STATUS
661 #define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA4_CURR_DESC_PTR
662 #define bfin_write_DMA_SPI_CONFIG bfin_write_DMA4_CONFIG
663 #elif defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__) || \
664 defined(__ADSPBF538__) || defined(__ADSPBF539__)
665 #define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA5_IRQ_STATUS
666 #define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA5_IRQ_STATUS
667 #define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA5_CURR_DESC_PTR
668 #define bfin_write_DMA_SPI_CONFIG bfin_write_DMA5_CONFIG
669 #elif defined(__ADSPBF561__)
670 #define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA16_IRQ_STATUS
671 #define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA16_IRQ_STATUS
672 #define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA16_CURR_DESC_PTR
673 #define bfin_write_DMA_SPI_CONFIG bfin_write_DMA16_CONFIG
674 #elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) || \
675 defined(__ADSPBF52x__) || defined(__ADSPBF51x__)
676 #define bfin_write_DMA_SPI_IRQ_STATUS bfin_write_DMA7_IRQ_STATUS
677 #define bfin_read_DMA_SPI_IRQ_STATUS bfin_read_DMA7_IRQ_STATUS
678 #define bfin_write_DMA_SPI_CURR_DESC_PTR bfin_write_DMA7_CURR_DESC_PTR
679 #define bfin_write_DMA_SPI_CONFIG bfin_write_DMA7_CONFIG
681 #error "Please provide SPI DMA channel defines"
684 struct dmadesc_array {
685 unsigned long start_addr;
687 unsigned short x_count;
689 unsigned short y_count;
691 } __attribute__((packed));
694 * Read a value from flash for verify purpose
695 * Inputs: unsigned long ulStart - holds the SPI start address
696 * int pnData - pointer to store value read from flash
697 * long lCount - number of elements to read
700 static int read_flash(unsigned long address, long count, uchar *buffer)
703 struct dmadesc_array dma[2];
704 /* Send the read command to SPI device */
709 dma[0].start_addr = (unsigned long)buffer;
711 if (count <= 65536) {
712 blackfin_dcache_flush_invalidate_range(buffer, buffer + count);
714 dma[0].cfg = NDSIZE_0 | WNR | WDSIZE_8 | FLOW_STOP | DMAEN | DI_EN;
715 dma[0].x_count = count;
717 blackfin_dcache_flush_invalidate_range(buffer, buffer + 65536 - 1);
719 dma[0].cfg = NDSIZE_5 | WNR | WDSIZE_8 | FLOW_ARRAY | DMAEN | DMA2D;
720 dma[0].x_count = 0; /* 2^16 */
721 dma[0].y_count = count >> 16; /* count / 2^16 */
723 dma[1].start_addr = (unsigned long)(buffer + (count & ~0xFFFF));
724 dma[1].cfg = NDSIZE_0 | WNR | WDSIZE_8 | FLOW_STOP | DMAEN | DI_EN;
725 dma[1].x_count = count & 0xFFFF; /* count % 2^16 */
729 bfin_write_DMA_SPI_CONFIG(0);
730 bfin_write_DMA_SPI_IRQ_STATUS(DMA_DONE | DMA_ERR);
731 bfin_write_DMA_SPI_CURR_DESC_PTR(dma);
735 spi_write_read_byte(flash.ops->read);
736 transmit_address(address);
738 #ifndef CONFIG_SPI_FLASH_SLOW_READ
739 /* Send dummy byte when doing SPI fast reads */
740 spi_write_read_byte(0);
743 bfin_write_DMA_SPI_CONFIG(ndsize | FLOW_ARRAY | DMAEN);
744 *pSPI_CTL = (MSTR | CPHA | CPOL | RDBR_DMA | SPE | SZ);
748 * We already invalidated the first 64k,
749 * now while we just wait invalidate the remaining part.
750 * Its not likely that the DMA is going to overtake
753 blackfin_dcache_flush_invalidate_range(buffer + 65536,
756 while (!(bfin_read_DMA_SPI_IRQ_STATUS() & DMA_DONE))
764 bfin_write_DMA_SPI_CONFIG(0);
766 *pSPI_CTL = (SPE | MSTR | CPHA | CPOL | TDBR_CORE);
772 static long address_to_sector(unsigned long address)
774 if (address > (flash.num_sectors * flash.sector_size) - 1)
776 return address / flash.sector_size;
779 static int erase_sector(int address)
781 /* sector gets checked in higher function, so assume it's valid
782 * here and figure out the offset of the sector in flash
784 if (enable_writing())
788 * Send the erase block command to the flash followed by the 24 address
789 * to point to the start of a sector
792 spi_write_read_byte(flash.ops->erase);
793 transmit_address(address);
796 return wait_for_ready_status();
799 /* Write [count] bytes out of [buffer] into the given SPI [address] */
800 static long write_flash(unsigned long address, long count, uchar *buffer)
802 long i, write_buffer_size;
804 if (enable_writing())
807 /* Send write command followed by the 24 bit address */
809 spi_write_read_byte(flash.ops->write);
810 transmit_address(address);
812 /* Shoot out a single write buffer */
813 write_buffer_size = min(count, flash.write_length);
814 for (i = 0; i < write_buffer_size; ++i)
815 spi_write_read_byte(buffer[i]);
819 /* Wait for the flash to do its thing */
820 if (wait_for_ready_status()) {
821 puts("SPI Program Time out! ");
828 /* Write [count] bytes out of [buffer] into the given SPI [address] */
829 static int write_sector(unsigned long address, long count, uchar *buffer)
834 write_cnt = write_flash(address, count, buffer);
838 /* Now that we've sent some bytes out to the flash, update
842 address += write_cnt;
846 /* return the appropriate error code */
851 * Function: spi_write
853 ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len)
855 unsigned long offset;
856 int start_sector, end_sector;
857 int start_byte, end_byte;
863 if (spi_detect_part())
866 offset = addr[0] << 16 | addr[1] << 8 | addr[2];
868 /* Get the start block number */
869 start_sector = address_to_sector(offset);
870 if (start_sector == -1) {
871 puts("Invalid sector! ");
874 end_sector = address_to_sector(offset + len - 1);
875 if (end_sector == -1) {
876 puts("Invalid sector! ");
880 /* Since flashes operate in sector units but the eeprom command
881 * operates as a continuous stream of bytes, we need to emulate
882 * the eeprom behavior. So here we read in the sector, overlay
883 * any bytes we're actually modifying, erase the sector, and
884 * then write back out the new sector.
886 temp = malloc(flash.sector_size);
888 puts("Malloc for sector failed! ");
892 for (num = start_sector; num <= end_sector; num++) {
893 unsigned long address = num * flash.sector_size;
895 /* XXX: should add an optimization when spanning sectors:
896 * No point in reading in a sector if we're going to be
897 * clobbering the whole thing. Need to also add a test
898 * case to make sure the optimization is correct.
900 if (read_flash(address, flash.sector_size, temp)) {
901 puts("Read sector failed! ");
906 start_byte = max(address, offset);
907 end_byte = address + flash.sector_size - 1;
908 if (end_byte > (offset + len))
909 end_byte = (offset + len - 1);
911 memcpy(temp + start_byte - address,
912 buffer + start_byte - offset,
913 end_byte - start_byte + 1);
915 if (erase_sector(address)) {
916 puts("Erase sector failed! ");
920 if (write_sector(address, flash.sector_size, temp)) {
921 puts("Write sector failed! ");
941 ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len)
943 unsigned long offset;
947 if (spi_detect_part())
950 offset = addr[0] << 16 | addr[1] << 8 | addr[2];
951 read_flash(offset, len, buffer);
960 * Spit out some useful information about the SPI eeprom
962 int eeprom_info(void)
968 if (spi_detect_part())
971 printf("SPI Device: %s 0x%02X (%s) 0x%02X 0x%02X\n"
972 "Parameters: num sectors = %lu, sector size = %lu, write size = %i\n"
973 "Flash Size: %lu mbit (%lu mbyte)\n"
975 flash.flash->name, flash.manufacturer_id, flash.manufacturer->name,
976 flash.device_id1, flash.device_id2, flash.num_sectors,
977 flash.sector_size, flash.write_length,
978 (flash.num_sectors * flash.sector_size) >> 17,
979 (flash.num_sectors * flash.sector_size) >> 20,
980 read_status_register());