Patchwork [PATCH/WIP] AT45DB011D flashing support

login
register
about
Submitter Aidan Thornton
Date 2012-08-17 16:53:31
Message ID <CAB=c7TpuctLh1ZCG-Rg_Yhz4gEL+pUC8cFU81ofXxdO63Rv3vg@mail.gmail.com>
Download mbox | patch
Permalink /patch/3714/
State Superseded
Headers show

Comments

Aidan Thornton - 2012-08-17 16:53:31
Hi,

The attached patch is a somewhat messy attempt to add support for the
AT45DB011D and potentially other AT45DBxxxD Atmel DataFlash chips.
I've tested flashing the AT45DB011D-like integrated Flash on the
Xilinx XC3S50AN with it and it appears to work. Not really ready to
merge, but carldani asked me to post this so he could see if it could
be combined with his old incomplete code for non-power-of-2 flash
chips. Should in theory be able to read all AT45DBxxxD chips as-is and
write all chips that have 256/264-byte pages with suitable additions
to flashchips.c.

Aidan

Patch

Index: flashrom.c
===================================================================
--- flashrom.c	(revision 1575)
+++ flashrom.c	(working copy)
@@ -687,6 +687,22 @@ 
 				break;
 		}
 		break;
+	case write_gran_264bytes:
+		for (j = 0; j < len / 264; j++) {
+			limit = min (264, len - j * 264);
+			/* Are 'have' and 'want' identical? */
+			if (!memcmp(have + j * 264, want + j * 264, limit))
+				continue;
+			/* have needs to be in erased state. */
+			for (i = 0; i < limit; i++)
+				if (have[j * 264 + i] != 0xff) {
+					result = 1;
+					break;
+				}
+			if (result)
+				break;
+		}
+		break;
 	default:
 		msg_cerr("%s: Unsupported granularity! Please report a bug at "
 			 "flashrom@flashrom.org\n", __func__);
@@ -733,6 +749,9 @@ 
 	case write_gran_256bytes:
 		stride = 256;
 		break;
+	case write_gran_264bytes:
+		stride = 264;
+		break;
 	default:
 		msg_cerr("%s: Unsupported granularity! Please report a bug at "
 			 "flashrom@flashrom.org\n", __func__);
@@ -1240,7 +1259,12 @@ 
 {
 	unsigned int starthere = 0, lenhere = 0;
 	int ret = 0, skip = 1, writecount = 0;
-	enum write_granularity gran = write_gran_256bytes; /* FIXME */
+	enum write_granularity gran = write_gran_256bytes; 
+	
+	if(flash->page_size == 264 || flash->page_size == 528) {
+		// FIXME - this is wrong for 528-byte blocks
+		gran =  write_gran_264bytes; 
+	}
 
 	/* curcontents and newcontents are opaque to walk_eraseregions, and
 	 * need to be adjusted here to keep the impression of proper abstraction
Index: Makefile
===================================================================
--- Makefile	(revision 1575)
+++ Makefile	(working copy)
@@ -285,7 +285,7 @@ 
 CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \
 	sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \
 	sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o \
-	a25.o at25.o opaque.o sfdp.o en29lv640b.o
+	a25.o at25.o opaque.o sfdp.o en29lv640b.o at45db.o
 
 ###############################################################################
 # Library code.
Index: flashchips.c
===================================================================
--- flashchips.c	(revision 1575)
+++ flashchips.c	(working copy)
@@ -2095,14 +2095,35 @@ 
 		.bustype	= BUS_SPI,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= ATMEL_AT45DB011D,
-		.total_size	= 128 /* Size can only be determined from status register */,
-		.page_size	= 256 /* Size can only be determined from status register */,
+		.total_size	= 128 /* or 132, determined from status register */,
+		.page_size	= 256 /* or 264, determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
-		.probe		= probe_spi_rdid,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_at45db,
 		.probe_timing	= TIMING_ZERO,
-		.write		= NULL,
-		.read		= NULL,
+		.block_erasers	=
+		{
+			/*{
+				.eraseblocks = { {256, 512} },
+				.block_erase = ????, //spi_erase_at45db_page,
+			}, {
+			{
+				.eraseblocks = { {8 * 256, 512/8} },
+				.block_erase = ????, //spi_erase_at45db_block,
+			},*/ {
+				.eraseblocks = {
+					{8 * 256, 1},
+					{120 * 256, 1},
+					{128 * 256, 3},
+				},
+				.block_erase = erase_at45db_sector
+			}/*, {
+				.eraseblocks = { {128 * 1024, 1} },
+				.block_erase = ????, //spi_block_erase_c7,
+			}*/
+		},
+		.write		= spi_write_at45db,
+		.read		= read_at45db,
 		.voltage	= {2700, 3600},
 	},
 
@@ -2113,13 +2134,13 @@ 
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= ATMEL_AT45DB021D,
 		.total_size	= 256 /* Size can only be determined from status register */,
-		.page_size	= 256 /* Size can only be determined from status register */,
+		.page_size	= 256 /* or 264, determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
-		.probe		= probe_spi_rdid,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_at45db,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
-		.read		= NULL,
+		.read		= read_at45db,
 		.voltage	= {2700, 3600},
 	},
 
@@ -2130,13 +2151,13 @@ 
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= ATMEL_AT45DB041D,
 		.total_size	= 512 /* Size can only be determined from status register */,
-		.page_size	= 256 /* Size can only be determined from status register */,
+		.page_size	= 256 /* or 264, determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
-		.probe		= probe_spi_rdid,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_at45db,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
-		.read		= NULL,
+		.read		= read_at45db,
 		.voltage	= {2500, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
 	},
 
@@ -2147,13 +2168,13 @@ 
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= ATMEL_AT45DB081D,
 		.total_size	= 1024 /* Size can only be determined from status register */,
-		.page_size	= 256 /* Size can only be determined from status register */,
+		.page_size	= 256 /* or 264, determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
-		.probe		= probe_spi_rdid,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_at45db,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
-		.read		= NULL,
+		.read		= read_at45db,
 		.voltage	= {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
 	},
 
@@ -2164,13 +2185,13 @@ 
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= ATMEL_AT45DB161D,
 		.total_size	= 2048 /* Size can only be determined from status register */,
-		.page_size	= 512 /* Size can only be determined from status register */,
+		.page_size	= 512 /* or 528, determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
-		.probe		= probe_spi_rdid,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_at45db,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
-		.read		= NULL,
+		.read		= read_at45db,
 		.voltage	= {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
 	},
 
Index: chipdrivers.h
===================================================================
--- chipdrivers.h	(revision 1575)
+++ chipdrivers.h	(working copy)
@@ -87,6 +87,15 @@ 
 int spi_disable_blockprotect_at25fs010(struct flashctx *flash);
 int spi_disable_blockprotect_at25fs040(struct flashctx *flash);
 
+/* at45db.c */
+int probe_spi_at45db(struct flashctx *flash);
+int read_at45db(struct flashctx *flash, uint8_t *buf, unsigned int start,
+	        unsigned int len);
+int erase_at45db_sector(struct flashctx *flash, unsigned int addr,
+			unsigned int blocklen);
+int spi_write_at45db(struct flashctx *flash, uint8_t *buf,
+		     unsigned int start, unsigned int len);
+
 /* 82802ab.c */
 uint8_t wait_82802ab(struct flashctx *flash);
 int probe_82802ab(struct flashctx *flash);
Index: flash.h
===================================================================
--- flash.h	(revision 1575)
+++ flash.h	(working copy)
@@ -227,6 +227,7 @@ 
 	write_gran_1bit,
 	write_gran_1byte,
 	write_gran_256bytes,
+	write_gran_264bytes,
 };
 extern int verbose_screen;
 extern int verbose_logfile;