On Thu, 2008-01-17 at 00:56 +0100, Carl-Daniel Hailfinger wrote:

> Please see
> http://www.coreboot.org/Development_Guidelines#Sign-off_Procedure for
> details on patch submission. There are two things that block acceptance
> of your patch:
> - A "Signed-off-by:" line is missing. Please add one.

I'll try again now... Sorry for my ignorance (or failure to read the
procedure).

> The function is probably more specific to IT8716F and chips bigger than
> 512 kByte. Maybe rename the function and have the IT8716F writing code
> switch to you method if the chip is bigger than 512 kB?
> 

I've made it a little more generic, but otoh, the spi.c is sort of less
generic than the filename would suggest, quite IT8716F specific.
I've made all spi flash chips over 512k point to the new functions and
hope that they will all work for them too (I cannot test this). With the
generic functions, it will definately not work because of the 8716's
512k limit, so it won't break anything that is not already broken...
But the lack of block-write seems to me is quite sst chip specific
(remember they have an AAI mode instead, which doesn't play well with
the limited io transfer length options of the IT8716). It might be more
appropriate to have an 'over512k_page_write' for more speed with chips
that do support that. Also the byte program wait time is hard wired to
10 us (following the 25vf016b datasheet). And the block protect
enablement might also NOT be so generic.

> 
> Please try to address the comments above and repost.
> Note: I suggest that the "maximum frequency" stuff could be handled in
> another patch because it requires redesign of some structures (needs
> discussion) and is also is logically another change.
> 

For now, the frequency is set to 33/2 for the new large flash functions,
pending a better approach.

The reworked attached patch also includes the added winbond (previously
known as Nexcom) chips.

Signed-off-by: Ronald Hoogenboom <[EMAIL PROTECTED]>

---
Index: flash.h
===================================================================
--- flash.h	(revision 3051)
+++ flash.h	(working copy)
@@ -247,6 +247,12 @@
 #define W_49V002A		0xB0
 #define W_49V002FA		0x32
 
+#define WINBOND_SPI_ID         0xEF    /* Winbond serial flash devices */
+#define W_25X10                        0x3011
+#define W_25X20                        0x3012
+#define W_25X40                        0x3013
+#define W_25X80                        0x3014
+
 /* udelay.c */
 void myusec_delay(int time);
 void myusec_calibrate_delay();
@@ -297,6 +303,8 @@
 void generic_spi_write_disable();
 int generic_spi_chip_erase_c7(struct flashchip *flash);
 int generic_spi_chip_write(struct flashchip *flash, uint8_t *buf);
+int over512k_spi_chip_write(struct flashchip *flash, uint8_t *buf);
+int over512k_spi_chip_read(struct flashchip *flash, uint8_t *buf);
 
 /* 82802ab.c */
 int probe_82802ab(struct flashchip *flash);
Index: flashchips.c
===================================================================
--- flashchips.c	(revision 3051)
+++ flashchips.c	(working copy)
@@ -53,11 +53,11 @@
 	{"MX25L4005",	MX_ID,		MX_25L4005,	512, 256,
 	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
 	{"MX25L8005",	MX_ID,		MX_25L8005,	1024, 256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"SST25VF040B",	SST_ID,		SST_25VF040B,	512,	256,
 	probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
 	{"SST25VF016B",	SST_ID,		SST_25VF016B,	2048,	256,
-	probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"SST29EE020A", SST_ID,		SST_29EE020A,	256, 128,
 	 probe_jedec,	erase_chip_jedec, write_jedec},
 	{"SST28SF040A", SST_ID,		SST_28SF040,	512, 256,
@@ -122,6 +122,14 @@
 	 probe_jedec,   erase_chip_jedec, write_39sf020},
 	{"W39V080A", 	WINBOND_ID, 	W_39V080A,	1024, 64*1024,
 	 probe_jedec,	erase_chip_jedec, write_39sf020},
+	{"W25x10",      WINBOND_SPI_ID, W_25X10,        128, 256, 
+	 probe_spi,     generic_spi_chip_erase_c7,      generic_spi_chip_write},
+	{"W25x20",      WINBOND_SPI_ID, W_25X20,        256, 256, 
+	 probe_spi,     generic_spi_chip_erase_c7,      generic_spi_chip_write},
+	{"W25x40",      WINBOND_SPI_ID, W_25X40,        512, 256, 
+	 probe_spi,     generic_spi_chip_erase_c7,      generic_spi_chip_write},
+	{"W25x80",      WINBOND_SPI_ID, W_25X80,        1024, 256, 
+	 probe_spi,     generic_spi_chip_erase_c7,      over512k_spi_chip_write, over512k_spi_chip_read},
 	{"M29F002B",	ST_ID, 		ST_M29F002B,	256, 64 * 1024,
 	 probe_jedec,	erase_chip_jedec, write_jedec},
 	{"M50FW040",	ST_ID, 		ST_M50FW040,	512, 64 * 1024,
@@ -159,15 +167,15 @@
 	{"M25P40",	ST_ID,		ST_M25P40,	512,	256,
 	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
 	{"M25P80",	ST_ID,		ST_M25P80,	1024,	256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"M25P16",	ST_ID,		ST_M25P16,	2048,	256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"M25P32",	ST_ID,		ST_M25P32,	4096,	256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"M25P64",	ST_ID,		ST_M25P64,	8192,	256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"M25P128",	ST_ID,		ST_M25P128,	16384,	256,
-	 probe_spi,	generic_spi_chip_erase_c7,	generic_spi_chip_write},
+	 probe_spi,	generic_spi_chip_erase_c7,	over512k_spi_chip_write, over512k_spi_chip_read},
 	{"82802ab",	137,		173,		512, 64 * 1024,
 	 probe_82802ab, erase_82802ab,	write_82802ab},
 	{"82802ac",	137,		172,		1024, 64 * 1024,
Index: spi.c
===================================================================
--- spi.c	(revision 3051)
+++ spi.c	(working copy)
@@ -77,6 +77,8 @@
 #define JEDEC_RDSR_BIT_WIP	(0x01 << 0)
 
 uint16_t it8716f_flashport = 0;
+/* use fast 33MHz SPI (<>0) or slow 16MHz (0) */
+int fast_spi=1;
 
 void generic_spi_prettyprint_status_register(struct flashchip *flash);
 
@@ -203,10 +205,10 @@
 			__FUNCTION__, writecnt);
 		return 1;
 	}
-	/* Start IO, 33MHz, readcnt input bytes, writecnt output bytes. Note:
+	/* Start IO, 33MHz (or 16), readcnt input bytes, writecnt output bytes. Note:
 	 * We can't use writecnt directly, but have to use a strange encoding.
 	 */ 
-	outb((0x5 << 4) | ((readcnt & 0x3) << 2) | (writeenc), port);
+	outb(((0x4+(fast_spi?1:0)) << 4) | ((readcnt & 0x3) << 2) | (writeenc), port);
 	do {
 		busy = inb(port) & 0x80;
 	} while (busy);
@@ -314,6 +316,39 @@
 		"%sset\n", (status & (1 << 0)) ? "" : "not ");
 }
 
+/* Prettyprint the status register. Works for
+ * SST 25VF016
+ */
+void generic_spi_prettyprint_status_register_sst25vf016(uint8_t status)
+{
+	const char *bpt[]={
+		"none",
+		"1F0000H-1FFFFFH",
+		"1E0000H-1FFFFFH",
+		"1C0000H-1FFFFFH",
+		"180000H-1FFFFFH",
+		"100000H-1FFFFFH",
+		"all","all"
+	};
+	printf_debug("Chip status register: Block Protect Write Disable "
+		"(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
+	printf_debug("Chip status register: Auto Address Increment Programming "
+		"(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
+	printf_debug("Chip status register: Bit 5 (BP3) is "
+		"%sset\n", (status & (1 << 5)) ? "" : "not ");
+	printf_debug("Chip status register: Bit 4 (BP2) is "
+		"%sset\n", (status & (1 << 4)) ? "" : "not ");
+	printf_debug("Chip status register: Bit 3 (BP1) is "
+		"%sset\n", (status & (1 << 3)) ? "" : "not ");
+	printf_debug("Chip status register: Bit 2 (BP0) is "
+		"%sset\n", (status & (1 << 2)) ? "" : "not ");
+	printf_debug("Resulting block protection : %s\n", bpt[(status&0x1c)>>2]);
+	printf_debug("Chip status register: Write Enable Latch (WEL) is "
+		"%sset\n", (status & (1 << 1)) ? "" : "not ");
+	printf_debug("Chip status register: Write In Progress (BUSY) is "
+		"%sset\n", (status & (1 << 0)) ? "" : "not ");
+}
+
 void generic_spi_prettyprint_status_register(struct flashchip *flash)
 {
 	uint8_t status;
@@ -326,6 +361,10 @@
 		if ((flash->model_id & 0xff00) == 0x2000)
 			generic_spi_prettyprint_status_register_st_m25p(status);
 		break;
+	case SST_ID:
+		if (flash->model_id == SST_25VF016B)
+			generic_spi_prettyprint_status_register_sst25vf016(status);
+		break;
 	}
 }
 	
@@ -392,7 +431,7 @@
 
 	generic_spi_write_enable();
 	outb(0x06 , it8716f_flashport + 1);
-	outb((3 << 4), it8716f_flashport);
+	outb(((2+(fast_spi?1:0)) << 4), it8716f_flashport);
 	for (i = 0; i < 256; i++) {
 		bios[256 * block + i] = buf[256 * block + i];
 	}
@@ -410,6 +449,94 @@
 		it8716f_spi_page_program(block, buf, bios);
 }
 
+/*
+ * This is according the SST25VF016 datasheet, who knows it is more
+ * generic that this...
+ */
+void spi_write_status_register(int status)
+{
+	const unsigned char cmd[] = {0x01,(unsigned char)status};
+
+	/* Send WRSR (Write Status Register) */
+	generic_spi_command(2, 0, cmd, NULL);
+
+}
+
+void spi_byte_program(int address, uint8_t byte)
+{
+	const unsigned char cmd[5] = {0x02,
+		(address>>16)&0xff,
+		(address>>8)&0xff,
+		(address>>0)&0xff,
+		byte
+	};
+
+	/* Send Byte-Program */
+	generic_spi_command(5, 0, cmd, NULL);
+
+}
+
+/*
+ * IT8716F only allows maximum of 512 kb SPI mapped to LPC memory cycles
+ * Program chip using firmware cycle byte programming. (SLOW!)
+ */
+int over512k_spi_chip_write(struct flashchip *flash, uint8_t *buf)
+{
+	int total_size = 1024 * flash->total_size;
+	uint8_t status;
+	int i;
+	fast_spi=0;
+
+	status = generic_spi_read_status_register();
+	/* If there is block protection in effect, unprotect it first. */
+	if ((status&0x3c)!=0) {
+		printf_debug("Some block protection in effect, disabling\n");
+		generic_spi_write_enable();
+		spi_write_status_register(status&~0x3c);
+	}
+	for (i=0; i<total_size; i++) {
+		generic_spi_write_enable();
+		spi_byte_program(i,buf[i]);
+		//while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+		myusec_delay(10);
+		//if (i%1024==0) fputc('b',stderr);
+	}
+	/* resume normal ops... */
+	outb(0x20, it8716f_flashport);
+	return 0;
+}
+
+void spi_3byte_read(int address, uint8_t *bytes, int len)
+{
+	const unsigned char cmd[5] = {0x03,
+		(address>>16)&0xff,
+		(address>>8)&0xff,
+		(address>>0)&0xff,
+	};
+
+	/* Send Read */
+	generic_spi_command(4, len, cmd, bytes);
+
+}
+
+/*
+ * IT8716F only allows maximum of 512 kb SPI mapped to LPC memory cycles
+ * Need to read this big flash using firmware cycles 3 byte at a time.
+ */
+int over512k_spi_chip_read(struct flashchip *flash, uint8_t *buf)
+{
+	int total_size = 1024 * flash->total_size;
+	int i;
+	fast_spi=0;
+
+	for (i = 0; i < total_size; i+=3) {
+		int toread=3;
+		if (total_size-i < toread) toread=total_size-i;
+		spi_3byte_read(i, buf+i, toread);
+	}
+	return 0;
+}
+
 int generic_spi_chip_write(struct flashchip *flash, uint8_t *buf) {
 	int total_size = 1024 * flash->total_size;
 	int i;
-- 
coreboot mailing list
coreboot@coreboot.org
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to