mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00
Convert SPI chips to partial write
However, wrap the write functions in a compat layer to allow converting the rest of flashrom later. Tested on Intel NM10 by David Hendricks. Corresponding to flashrom svn r1080. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
This commit is contained in:
parent
1748c5701f
commit
9a795d83fb
@ -139,10 +139,8 @@ int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf)
|
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int total_size = 1024 * flash->total_size;
|
spi_disable_blockprotect();
|
||||||
|
return spi_write_chunked(flash, buf, start, len, 256);
|
||||||
msg_pdbg("total_size is %d\n", total_size);
|
|
||||||
return spi_write_chunked(flash, buf, 0, total_size, 256);
|
|
||||||
}
|
}
|
||||||
|
@ -309,18 +309,8 @@ int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len
|
|||||||
return spi_read_chunked(flash, buf, start, len, 12);
|
return spi_read_chunked(flash, buf, start, len, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf)
|
int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int total_size = 1024 * flash->total_size;
|
|
||||||
|
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first. */
|
return spi_write_chunked(flash, buf, start, len, 12);
|
||||||
msg_pinfo("Erasing flash before programming... ");
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_perr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
msg_pinfo("done.\n");
|
|
||||||
|
|
||||||
return spi_write_chunked(flash, buf, 0, total_size, 12);
|
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ int spi_block_erase_60(struct flashchip *flash, unsigned int addr, unsigned int
|
|||||||
int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
|
int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
|
||||||
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf);
|
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf);
|
||||||
int spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
|
int spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
|
||||||
|
int spi_chip_write_1_new(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
int spi_chip_write_256_new(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
uint8_t spi_read_status_register(void);
|
uint8_t spi_read_status_register(void);
|
||||||
int spi_disable_blockprotect(void);
|
int spi_disable_blockprotect(void);
|
||||||
@ -51,7 +53,7 @@ int spi_nbyte_program(int addr, uint8_t *bytes, int len);
|
|||||||
int spi_nbyte_read(int addr, uint8_t *bytes, int len);
|
int spi_nbyte_read(int addr, uint8_t *bytes, int len);
|
||||||
int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
|
int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
|
||||||
int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
|
int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
|
||||||
int spi_aai_write(struct flashchip *flash, uint8_t *buf);
|
int spi_aai_write(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* 82802ab.c */
|
/* 82802ab.c */
|
||||||
uint8_t wait_82802ab(chipaddr bios);
|
uint8_t wait_82802ab(chipaddr bios);
|
||||||
|
@ -167,3 +167,12 @@ int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Is is impossible to trigger this code path because dummyflasher probing will
|
||||||
|
* never be successful, and the current frontend refuses to write in that case.
|
||||||
|
* Other frontends may allow writing even for non-detected chips, though.
|
||||||
|
*/
|
||||||
|
int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
|
{
|
||||||
|
spi_disable_blockprotect();
|
||||||
|
return spi_write_chunked(flash, buf, start, len, 256);
|
||||||
|
}
|
||||||
|
17
flash.h
17
flash.h
@ -456,6 +456,7 @@ void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
|
|||||||
int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int dummy_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
const unsigned char *writearr, unsigned char *readarr);
|
const unsigned char *writearr, unsigned char *readarr);
|
||||||
int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* nic3com.c */
|
/* nic3com.c */
|
||||||
@ -529,7 +530,7 @@ extern const struct pcidev_status ata_hpt[];
|
|||||||
int ft2232_spi_init(void);
|
int ft2232_spi_init(void);
|
||||||
int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
||||||
int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
|
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* bitbang_spi.c */
|
/* bitbang_spi.c */
|
||||||
extern int bitbang_spi_half_period;
|
extern int bitbang_spi_half_period;
|
||||||
@ -537,7 +538,7 @@ extern const struct bitbang_spi_master_entry bitbang_spi_master_table[];
|
|||||||
int bitbang_spi_init(void);
|
int bitbang_spi_init(void);
|
||||||
int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
||||||
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf);
|
int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* buspirate_spi.c */
|
/* buspirate_spi.c */
|
||||||
struct buspirate_spispeeds {
|
struct buspirate_spispeeds {
|
||||||
@ -548,7 +549,7 @@ int buspirate_spi_init(void);
|
|||||||
int buspirate_spi_shutdown(void);
|
int buspirate_spi_shutdown(void);
|
||||||
int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
|
||||||
int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf);
|
int buspirate_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* dediprog.c */
|
/* dediprog.c */
|
||||||
int dediprog_init(void);
|
int dediprog_init(void);
|
||||||
@ -668,7 +669,7 @@ struct spi_programmer {
|
|||||||
|
|
||||||
/* Optimized functions for this programmer */
|
/* Optimized functions for this programmer */
|
||||||
int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int (*read)(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int (*write_256)(struct flashchip *flash, uint8_t *buf);
|
int (*write_256)(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum spi_controller spi_controller;
|
extern enum spi_controller spi_controller;
|
||||||
@ -689,7 +690,7 @@ int ich_init_opcodes(void);
|
|||||||
int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
const unsigned char *writearr, unsigned char *readarr);
|
const unsigned char *writearr, unsigned char *readarr);
|
||||||
int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
|
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf, int start, int len);
|
||||||
int ich_spi_send_multicommand(struct spi_command *cmds);
|
int ich_spi_send_multicommand(struct spi_command *cmds);
|
||||||
|
|
||||||
/* it87spi.c */
|
/* it87spi.c */
|
||||||
@ -701,13 +702,13 @@ int it87spi_init(void);
|
|||||||
int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
const unsigned char *writearr, unsigned char *readarr);
|
const unsigned char *writearr, unsigned char *readarr);
|
||||||
int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
|
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* sb600spi.c */
|
/* sb600spi.c */
|
||||||
int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
const unsigned char *writearr, unsigned char *readarr);
|
const unsigned char *writearr, unsigned char *readarr);
|
||||||
int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf);
|
int sb600_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
extern uint8_t *sb600_spibar;
|
extern uint8_t *sb600_spibar;
|
||||||
|
|
||||||
/* wbsio_spi.c */
|
/* wbsio_spi.c */
|
||||||
@ -715,7 +716,7 @@ int wbsio_check_for_spi(void);
|
|||||||
int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int wbsio_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
const unsigned char *writearr, unsigned char *readarr);
|
const unsigned char *writearr, unsigned char *readarr);
|
||||||
int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf);
|
int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* serprog.c */
|
/* serprog.c */
|
||||||
int serprog_init(void);
|
int serprog_init(void);
|
||||||
|
@ -1423,7 +1423,7 @@ struct flashchip flashchips[] = {
|
|||||||
.block_erase = spi_block_erase_c7,
|
.block_erase = spi_block_erase_c7,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.write = spi_aai_write,
|
.write = spi_chip_write_1,
|
||||||
.read = spi_chip_read,
|
.read = spi_chip_read,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
14
ft2232_spi.c
14
ft2232_spi.c
@ -288,20 +288,10 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
return spi_read_chunked(flash, buf, start, len, 64 * 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf)
|
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int total_size = 1024 * flash->total_size;
|
|
||||||
|
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first. */
|
return spi_write_chunked(flash, buf, start, len, 256);
|
||||||
msg_pinfo("Erasing flash before programming... ");
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_perr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
msg_pinfo("done.\n");
|
|
||||||
msg_pdbg("total_size is %d\n", total_size);
|
|
||||||
return spi_write_chunked(flash, buf, 0, total_size, 256);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
25
ichspi.c
25
ichspi.c
@ -683,36 +683,15 @@ int ich_spi_read(struct flashchip *flash, uint8_t * buf, int start, int len)
|
|||||||
return spi_read_chunked(flash, buf, start, len, maxdata);
|
return spi_read_chunked(flash, buf, start, len, maxdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf)
|
int ich_spi_write_256(struct flashchip *flash, uint8_t * buf, int start, int len)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
|
||||||
int total_size = flash->total_size * 1024;
|
|
||||||
int erase_size = 64 * 1024;
|
|
||||||
int maxdata = 64;
|
int maxdata = 64;
|
||||||
|
|
||||||
if (spi_controller == SPI_CONTROLLER_VIA)
|
if (spi_controller == SPI_CONTROLLER_VIA)
|
||||||
maxdata = 16;
|
maxdata = 16;
|
||||||
|
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first */
|
return spi_write_chunked(flash, buf, start, len, maxdata);
|
||||||
msg_pinfo("Erasing flash before programming... ");
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_perr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
msg_pinfo("done.\n");
|
|
||||||
|
|
||||||
msg_pinfo("Programming page: \n");
|
|
||||||
for (i = 0; i < total_size / erase_size; i++) {
|
|
||||||
ret = spi_write_chunked(flash, buf + (i * erase_size),
|
|
||||||
i * erase_size, erase_size, maxdata);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_pinfo("\n");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
|
42
it87spi.c
42
it87spi.c
@ -292,7 +292,7 @@ int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Page size is usually 256 bytes */
|
/* Page size is usually 256 bytes */
|
||||||
static int it8716f_spi_page_program(struct flashchip *flash, int block, uint8_t *buf)
|
static int it8716f_spi_page_program(struct flashchip *flash, uint8_t *buf, int start)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int result;
|
int result;
|
||||||
@ -305,7 +305,7 @@ static int it8716f_spi_page_program(struct flashchip *flash, int block, uint8_t
|
|||||||
OUTB(0x06, it8716f_flashport + 1);
|
OUTB(0x06, it8716f_flashport + 1);
|
||||||
OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
|
OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
chip_writeb(buf[256 * block + i], bios + 256 * block + i);
|
chip_writeb(buf[i], bios + start + i);
|
||||||
}
|
}
|
||||||
OUTB(0, it8716f_flashport);
|
OUTB(0, it8716f_flashport);
|
||||||
/* Wait until the Write-In-Progress bit is cleared.
|
/* Wait until the Write-In-Progress bit is cleared.
|
||||||
@ -334,29 +334,39 @@ int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
|
int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int total_size = 1024 * flash->total_size;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IT8716F only allows maximum of 512 kb SPI chip size for memory
|
* IT8716F only allows maximum of 512 kb SPI chip size for memory
|
||||||
* mapped access.
|
* mapped access.
|
||||||
*/
|
*/
|
||||||
if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
|
if ((programmer == PROGRAMMER_IT87SPI) || (flash->total_size * 1024 > 512 * 1024)) {
|
||||||
spi_chip_write_1(flash, buf);
|
spi_chip_write_1_new(flash, buf, start, len);
|
||||||
} else {
|
} else {
|
||||||
|
int lenhere;
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first */
|
|
||||||
msg_pinfo("Erasing flash before programming... ");
|
if (start % 256) {
|
||||||
if (erase_flash(flash)) {
|
/* start to the end of the page or start + len,
|
||||||
msg_perr("ERASE FAILED!\n");
|
* whichever is smaller. Page length is hardcoded to
|
||||||
return -1;
|
* 256 bytes (IT87 SPI hardware limitation).
|
||||||
|
*/
|
||||||
|
lenhere = min(len, (start | 0xff) - start + 1);
|
||||||
|
spi_chip_write_1_new(flash, buf, start, lenhere);
|
||||||
|
start += lenhere;
|
||||||
|
len -= lenhere;
|
||||||
|
buf += lenhere;
|
||||||
}
|
}
|
||||||
msg_pinfo("done.\n");
|
|
||||||
for (i = 0; i < total_size / 256; i++) {
|
/* FIXME: Handle chips which have max writechunk size >1 and <256. */
|
||||||
it8716f_spi_page_program(flash, i, buf);
|
while (len >= 256) {
|
||||||
|
it8716f_spi_page_program(flash, buf, start);
|
||||||
|
start += 256;
|
||||||
|
len -= 256;
|
||||||
|
buf += 256;
|
||||||
}
|
}
|
||||||
|
if (len)
|
||||||
|
spi_chip_write_1_new(flash, buf, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
19
sb600spi.c
19
sb600spi.c
@ -48,25 +48,10 @@ int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
return spi_read_chunked(flash, buf, start, len, 8);
|
return spi_read_chunked(flash, buf, start, len, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: SB600 can write 5 bytes per transaction. */
|
int sb600_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf)
|
|
||||||
{
|
{
|
||||||
int total_size = flash->total_size * 1024;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first */
|
return spi_write_chunked(flash, buf, start, len, 5);
|
||||||
msg_pinfo("Erasing flash before programming... ");
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_perr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
msg_pinfo("done.\n");
|
|
||||||
|
|
||||||
msg_pinfo("Programming flash");
|
|
||||||
result = spi_write_chunked(flash, buf, 0, total_size, 5);
|
|
||||||
msg_pinfo(" done.\n");
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_internal_fifo_pointer(void)
|
static void reset_internal_fifo_pointer(void)
|
||||||
|
34
spi.c
34
spi.c
@ -66,7 +66,7 @@ const struct spi_programmer spi_programmer[] = {
|
|||||||
.command = sb600_spi_send_command,
|
.command = sb600_spi_send_command,
|
||||||
.multicommand = default_spi_send_multicommand,
|
.multicommand = default_spi_send_multicommand,
|
||||||
.read = sb600_spi_read,
|
.read = sb600_spi_read,
|
||||||
.write_256 = sb600_spi_write_1,
|
.write_256 = sb600_spi_write_256,
|
||||||
},
|
},
|
||||||
|
|
||||||
{ /* SPI_CONTROLLER_VIA */
|
{ /* SPI_CONTROLLER_VIA */
|
||||||
@ -99,7 +99,7 @@ const struct spi_programmer spi_programmer[] = {
|
|||||||
.command = dummy_spi_send_command,
|
.command = dummy_spi_send_command,
|
||||||
.multicommand = default_spi_send_multicommand,
|
.multicommand = default_spi_send_multicommand,
|
||||||
.read = dummy_spi_read,
|
.read = dummy_spi_read,
|
||||||
.write_256 = NULL,
|
.write_256 = dummy_spi_write_256,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ const struct spi_programmer spi_programmer[] = {
|
|||||||
.command = dediprog_spi_send_command,
|
.command = dediprog_spi_send_command,
|
||||||
.multicommand = default_spi_send_multicommand,
|
.multicommand = default_spi_send_multicommand,
|
||||||
.read = dediprog_spi_read,
|
.read = dediprog_spi_read,
|
||||||
.write_256 = spi_chip_write_1,
|
.write_256 = spi_chip_write_1_new,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -196,8 +196,11 @@ int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
/*
|
/*
|
||||||
* Program chip using page (256 bytes) programming.
|
* Program chip using page (256 bytes) programming.
|
||||||
* Some SPI masters can't do this, they use single byte programming instead.
|
* Some SPI masters can't do this, they use single byte programming instead.
|
||||||
|
* The redirect to single byte programming is achieved by setting
|
||||||
|
* .write_256 = spi_chip_write_1
|
||||||
*/
|
*/
|
||||||
int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
|
/* real chunksize is up to 256, logical chunksize is 256 */
|
||||||
|
int spi_chip_write_256_new(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
if (!spi_programmer[spi_controller].write_256) {
|
if (!spi_programmer[spi_controller].write_256) {
|
||||||
msg_perr("%s called, but SPI page write is unsupported on this "
|
msg_perr("%s called, but SPI page write is unsupported on this "
|
||||||
@ -206,7 +209,28 @@ int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return spi_programmer[spi_controller].write_256(flash, buf);
|
return spi_programmer[spi_controller].write_256(flash, buf, start, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function until the generic code is converted to partial writes. */
|
||||||
|
int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
spi_disable_blockprotect();
|
||||||
|
msg_pinfo("Erasing flash before programming... ");
|
||||||
|
if (erase_flash(flash)) {
|
||||||
|
msg_perr("ERASE FAILED!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
msg_pinfo("done.\n");
|
||||||
|
msg_pinfo("Programming flash... ");
|
||||||
|
ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024);
|
||||||
|
if (!ret)
|
||||||
|
msg_pinfo("done.\n");
|
||||||
|
else
|
||||||
|
msg_pinfo("\n");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
60
spi25.c
60
spi25.c
@ -874,6 +874,7 @@ int spi_nbyte_read(int address, uint8_t *bytes, int len)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a part of the flash chip.
|
* Read a part of the flash chip.
|
||||||
|
* FIXME: Use the chunk code from Michael Karcher instead.
|
||||||
* Each page is read separately in chunks with a maximum size of chunksize.
|
* Each page is read separately in chunks with a maximum size of chunksize.
|
||||||
*/
|
*/
|
||||||
int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
|
int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
|
||||||
@ -913,6 +914,7 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Write a part of the flash chip.
|
* Write a part of the flash chip.
|
||||||
|
* FIXME: Use the chunk code from Michael Karcher instead.
|
||||||
* Each page is written separately in chunks with a maximum size of chunksize.
|
* Each page is written separately in chunks with a maximum size of chunksize.
|
||||||
*/
|
*/
|
||||||
int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
|
int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize)
|
||||||
@ -963,20 +965,13 @@ int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
|
|||||||
* and for chips where memory mapped programming is impossible
|
* and for chips where memory mapped programming is impossible
|
||||||
* (e.g. due to size constraints in IT87* for over 512 kB)
|
* (e.g. due to size constraints in IT87* for over 512 kB)
|
||||||
*/
|
*/
|
||||||
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
|
/* real chunksize is 1, logical chunksize is 1 */
|
||||||
|
int spi_chip_write_1_new(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int total_size = 1024 * flash->total_size;
|
|
||||||
int i, result = 0;
|
int i, result = 0;
|
||||||
|
|
||||||
spi_disable_blockprotect();
|
spi_disable_blockprotect();
|
||||||
/* Erase first */
|
for (i = start; i < start + len; i++) {
|
||||||
msg_cinfo("Erasing flash before programming... ");
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_cerr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
msg_cinfo("done.\n");
|
|
||||||
for (i = 0; i < total_size; i++) {
|
|
||||||
result = spi_byte_program(i, buf[i]);
|
result = spi_byte_program(i, buf[i]);
|
||||||
if (result)
|
if (result)
|
||||||
return 1;
|
return 1;
|
||||||
@ -987,11 +982,23 @@ int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spi_aai_write(struct flashchip *flash, uint8_t *buf)
|
int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
uint32_t addr = 0;
|
spi_disable_blockprotect();
|
||||||
uint32_t len = flash->total_size * 1024;
|
/* Erase first */
|
||||||
uint32_t pos = addr;
|
msg_cinfo("Erasing flash before programming... ");
|
||||||
|
if (erase_flash(flash)) {
|
||||||
|
msg_cerr("ERASE FAILED!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
msg_cinfo("done.\n");
|
||||||
|
|
||||||
|
return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_aai_write(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
|
{
|
||||||
|
uint32_t pos = start;
|
||||||
int result;
|
int result;
|
||||||
unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = {
|
unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = {
|
||||||
JEDEC_AAI_WORD_PROGRAM,
|
JEDEC_AAI_WORD_PROGRAM,
|
||||||
@ -1006,9 +1013,9 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf)
|
|||||||
.writecnt = JEDEC_AAI_WORD_PROGRAM_OUTSIZE,
|
.writecnt = JEDEC_AAI_WORD_PROGRAM_OUTSIZE,
|
||||||
.writearr = (const unsigned char[]){
|
.writearr = (const unsigned char[]){
|
||||||
JEDEC_AAI_WORD_PROGRAM,
|
JEDEC_AAI_WORD_PROGRAM,
|
||||||
(pos >> 16) & 0xff,
|
(start >> 16) & 0xff,
|
||||||
(pos >> 8) & 0xff,
|
(start >> 8) & 0xff,
|
||||||
(pos & 0xff),
|
(start & 0xff),
|
||||||
buf[0],
|
buf[0],
|
||||||
buf[1]
|
buf[1]
|
||||||
},
|
},
|
||||||
@ -1026,17 +1033,21 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf)
|
|||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
case SPI_CONTROLLER_IT87XX:
|
case SPI_CONTROLLER_IT87XX:
|
||||||
case SPI_CONTROLLER_WBSIO:
|
case SPI_CONTROLLER_WBSIO:
|
||||||
msg_cerr("%s: impossible with this SPI controller,"
|
msg_perr("%s: impossible with this SPI controller,"
|
||||||
" degrading to byte program\n", __func__);
|
" degrading to byte program\n", __func__);
|
||||||
return spi_chip_write_1(flash, buf);
|
return spi_chip_write_1_new(flash, buf, start, len);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The even start address and even length requirements can be either
|
||||||
|
* honored outside this function, or we can call spi_byte_program
|
||||||
|
* for the first and/or last byte and use AAI for the rest.
|
||||||
|
*/
|
||||||
/* The data sheet requires a start address with the low bit cleared. */
|
/* The data sheet requires a start address with the low bit cleared. */
|
||||||
if (addr % 2) {
|
if (start % 2) {
|
||||||
msg_cerr("%s: start address not even! Please report a bug at "
|
msg_cerr("%s: start address not even! Please report a bug at "
|
||||||
"flashrom@flashrom.org\n", __func__);
|
"flashrom@flashrom.org\n", __func__);
|
||||||
return SPI_GENERIC_ERROR;
|
return SPI_GENERIC_ERROR;
|
||||||
@ -1048,15 +1059,14 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf)
|
|||||||
return SPI_GENERIC_ERROR;
|
return SPI_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (erase_flash(flash)) {
|
|
||||||
msg_cerr("ERASE FAILED!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = spi_send_multicommand(cmds);
|
result = spi_send_multicommand(cmds);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg_cerr("%s failed during start command execution\n",
|
msg_cerr("%s failed during start command execution\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
/* FIXME: Should we send WRDI here as well to make sure the chip
|
||||||
|
* is not in AAI mode?
|
||||||
|
*/
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
|
while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
|
||||||
@ -1065,7 +1075,7 @@ int spi_aai_write(struct flashchip *flash, uint8_t *buf)
|
|||||||
/* We already wrote 2 bytes in the multicommand step. */
|
/* We already wrote 2 bytes in the multicommand step. */
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
while (pos < addr + len) {
|
while (pos < start + len) {
|
||||||
cmd[1] = buf[pos++];
|
cmd[1] = buf[pos++];
|
||||||
cmd[2] = buf[pos++];
|
cmd[2] = buf[pos++];
|
||||||
spi_send_command(JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL);
|
spi_send_command(JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL);
|
||||||
|
@ -189,16 +189,14 @@ int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
|
|||||||
return read_memmapped(flash, buf, start, len);
|
return read_memmapped(flash, buf, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf)
|
int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf, int start, int len)
|
||||||
{
|
{
|
||||||
int size = flash->total_size * 1024;
|
if (flash->total_size * 1024 > 1024 * 1024) {
|
||||||
|
|
||||||
if (size > 1024 * 1024) {
|
|
||||||
msg_perr("%s: Winbond saved on 4 register bits so max chip size is 1024 KB!\n", __func__);
|
msg_perr("%s: Winbond saved on 4 register bits so max chip size is 1024 KB!\n", __func__);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return spi_chip_write_1(flash, buf);
|
return spi_chip_write_1_new(flash, buf, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user