mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-11-04 07:00:39 +01:00 
			
		
		
		
	Add support for AT45CS1282
This one is even more strange than the AT45DB chips. Like the AT45DB321C it does not support any power-of-2 page sizes. There is only one asymmetrical eraser and that uses two opcodes. Corresponding to flashrom svn r1725. Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
		
							
								
								
									
										41
									
								
								at45db.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								at45db.c
									
									
									
									
									
								
							@@ -419,6 +419,47 @@ int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned in
 | 
				
			|||||||
	return at45db_erase(flash, AT45DB_CHIP_ERASE, AT45DB_CHIP_ERASE_ADDR, 500000, 200);
 | 
						return at45db_erase(flash, AT45DB_CHIP_ERASE, AT45DB_CHIP_ERASE_ADDR, 500000, 200);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This one is really special and works only for AT45CS1282. It uses two different opcodes depending on the
 | 
				
			||||||
 | 
					 * address and has an asymmetric layout. */
 | 
				
			||||||
 | 
					int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const unsigned int page_size = flash->chip->page_size;
 | 
				
			||||||
 | 
						const unsigned int total_size = flash->chip->total_size * 1024;
 | 
				
			||||||
 | 
						const struct block_eraser be = flash->chip->block_erasers[0];
 | 
				
			||||||
 | 
						const unsigned int sec_0a_top = be.eraseblocks[0].size;
 | 
				
			||||||
 | 
						const unsigned int sec_0b_top = be.eraseblocks[0].size + be.eraseblocks[1].size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((addr + blocklen) > total_size) {
 | 
				
			||||||
 | 
							msg_cerr("%s: tried to erase a sector beyond flash boundary: addr=%u, blocklen=%u, size=%u\n",
 | 
				
			||||||
 | 
								 __func__, addr, blocklen, total_size);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool partial_range = false;
 | 
				
			||||||
 | 
						uint8_t opcode = 0x7C; /* Used for all but sector 0a. */
 | 
				
			||||||
 | 
						if (addr < sec_0a_top) {
 | 
				
			||||||
 | 
							opcode = 0x50;
 | 
				
			||||||
 | 
							/* One single sector of 8 pages at address 0. */
 | 
				
			||||||
 | 
							if (addr != 0 || blocklen != (8 * page_size))
 | 
				
			||||||
 | 
								partial_range = true;
 | 
				
			||||||
 | 
						} else if (addr < sec_0b_top) {
 | 
				
			||||||
 | 
							/* One single sector of 248 pages adjacent to the first. */
 | 
				
			||||||
 | 
							if (addr != sec_0a_top || blocklen != (248 * page_size))
 | 
				
			||||||
 | 
								partial_range = true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/* The rest is filled by 63 aligned sectors of 256 pages. */
 | 
				
			||||||
 | 
							if ((addr % (256 * page_size)) != 0 || (blocklen % (256 * page_size)) != 0)
 | 
				
			||||||
 | 
								partial_range = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (partial_range) {
 | 
				
			||||||
 | 
							msg_cerr("%s: cannot erase partial sectors: addr=%u, blocklen=%u\n", __func__, addr, blocklen);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Needs up to 4 s for completion, so let's wait 20 seconds in 200 ms steps. */
 | 
				
			||||||
 | 
						return at45db_erase(flash, opcode, at45db_convert_addr(addr, page_size), 200000, 100);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int at45db_fill_buffer1(struct flashctx *flash, uint8_t *bytes, unsigned int off, unsigned int len)
 | 
					static int at45db_fill_buffer1(struct flashctx *flash, uint8_t *bytes, unsigned int off, unsigned int len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const unsigned int page_size = flash->chip->page_size;
 | 
						const unsigned int page_size = flash->chip->page_size;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,6 +121,7 @@ int spi_erase_at45db_page(struct flashctx *flash, unsigned int addr, unsigned in
 | 
				
			|||||||
int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
					int spi_erase_at45db_block(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
				
			||||||
int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
					int spi_erase_at45db_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
				
			||||||
int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
					int spi_erase_at45db_chip(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
				
			||||||
 | 
					int spi_erase_at45cs_sector(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 82802ab.c */
 | 
					/* 82802ab.c */
 | 
				
			||||||
uint8_t wait_82802ab(struct flashctx *flash);
 | 
					uint8_t wait_82802ab(struct flashctx *flash);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								flashchips.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								flashchips.c
									
									
									
									
									
								
							@@ -2323,11 +2323,26 @@ const struct flashchip flashchips[] = {
 | 
				
			|||||||
		.total_size	= 16896 /* No power of two sizes */,
 | 
							.total_size	= 16896 /* No power of two sizes */,
 | 
				
			||||||
		.page_size	= 1056 /* No power of two sizes */,
 | 
							.page_size	= 1056 /* No power of two sizes */,
 | 
				
			||||||
		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
 | 
							/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
 | 
				
			||||||
		.tested		= TEST_BAD_REW,
 | 
							/* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
 | 
				
			||||||
 | 
							.feature_bits	= FEATURE_OTP,
 | 
				
			||||||
 | 
							.tested		= TEST_UNTESTED,
 | 
				
			||||||
		.probe		= probe_spi_rdid,
 | 
							.probe		= probe_spi_rdid,
 | 
				
			||||||
		.probe_timing	= TIMING_ZERO,
 | 
							.probe_timing	= TIMING_ZERO,
 | 
				
			||||||
		.write		= NULL /* Incompatible Page write */,
 | 
							.block_erasers	=
 | 
				
			||||||
		.read		= NULL /* Incompatible read */,
 | 
							{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									.eraseblocks = {
 | 
				
			||||||
 | 
										{8 * 1056, 1},    /* sector 0a:      opcode 50h */
 | 
				
			||||||
 | 
										{248 * 1056, 1},  /* sector 0b:      opcode 7Ch */
 | 
				
			||||||
 | 
										{256 * 1056, 63}, /* sectors 1 - 63: opcode 7Ch */
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									.block_erase = spi_erase_at45cs_sector,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.printlock	= spi_prettyprint_status_register_plain,
 | 
				
			||||||
 | 
							.gran		= write_gran_1056bytes,
 | 
				
			||||||
 | 
							.write		= spi_write_at45db,
 | 
				
			||||||
 | 
							.read		= spi_read_at45db,
 | 
				
			||||||
		.voltage	= {2700, 3600},
 | 
							.voltage	= {2700, 3600},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user