===================================================================
@@ -7523,9 +7523,9 @@
.total_size = 256,
.page_size = 64 * 1024,
.feature_bits = FEATURE_REGISTERMAP,
- .tested = TEST_UNTESTED,
+ .tested = TEST_OK_PREW,
.probe = probe_82802ab,
- .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
.block_erasers =
{
{
@@ -7536,9 +7536,12 @@
{16 * 1024, 1},
},
.block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = { {256 * 1024, 1}, },
+ .block_erase = NULL, /* Only in A/A mux mode */
}
},
- .unlock = unlock_stm50flw0x0x,
+ .unlock = unlock_stm50fw002,
.write = write_82802ab,
.read = read_memmapped,
.voltage = {3000, 3600}, /* Also has 12V fast program & erase */
===================================================================
@@ -3,6 +3,7 @@
*
* Copyright (C) 2008 Claus Gindhart <claus.gindhart@kontron.com>
* Copyright (C) 2009 Sean Nelson <audiohacked@gmail.com>
+ * Copyright (C) 2011 Carl-Daniel Hailfinger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +32,21 @@
#include "flashchips.h"
#include "chipdrivers.h"
+#define STM50_UNLOCKED 0x00
+
+static int unlock_block_stm50(struct flashchip *flash, int offset)
+{
+ chipaddr lock = flash->virtual_registers + offset + 2;
+
+ msg_cdbg("Unlocking at 0x%x\n", offset);
+ chip_writeb(STM50_UNLOCKED, lock);
+ if (chip_readb(lock) != STM50_UNLOCKED) {
+ msg_cerr("Cannot unlock at 0x%x\n", offset);
+ return -1;
+ }
+ return 0;
+}
+
/*
* claus.gindhart@kontron.com
* The ST M50FLW080B and STM50FLW080B chips have to be unlocked,
@@ -38,8 +54,6 @@
*/
static int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset)
{
- chipaddr wrprotect = flash->virtual_registers + 2;
- static const uint8_t unlock_sector = 0x00;
int j;
/*
@@ -58,22 +72,12 @@
|| (offset == 0xF0000)) {
// unlock each 4k-sector
- for (j = 0; j < 0x10000; j += 0x1000) {
- msg_cdbg("unlocking at 0x%x\n", offset + j);
- chip_writeb(unlock_sector, wrprotect + offset + j);
- if (chip_readb(wrprotect + offset + j) != unlock_sector) {
- msg_cerr("Cannot unlock sector @ 0x%x\n",
- offset + j);
+ for (j = 0; j < 0x10000; j += 0x1000)
+ if (unlock_block_stm50(flash, offset + j))
return -1;
- }
- }
} else {
- msg_cdbg("unlocking at 0x%x\n", offset);
- chip_writeb(unlock_sector, wrprotect + offset);
- if (chip_readb(wrprotect + offset) != unlock_sector) {
- msg_cerr("Cannot unlock sector @ 0x%x\n", offset);
+ if (unlock_block_stm50(flash, offset))
return -1;
- }
}
return 0;
@@ -93,6 +97,27 @@
return 0;
}
+/* FIXME: Should this be moved to a generic walk_unlockregions()? */
+int unlock_stm50fw002(struct flashchip *flash)
+{
+ static const struct eraseblock unlockregions[4] = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1}};
+ int i, j;
+ int addr = 0;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < unlockregions[i].count; j++) {
+ if (unlock_block_stm50(flash, addr))
+ return 1;
+ addr += unlockregions[i].size;
+ }
+ }
+ return 0;
+}
+
/* This function is unused. */
int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize)
{
===================================================================
@@ -146,5 +146,6 @@
/* stm50flw0x0x.c */
int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int block, unsigned int blocksize);
int unlock_stm50flw0x0x(struct flashchip *flash);
+int unlock_stm50fw002(struct flashchip *flash);
#endif /* !__CHIPDRIVERS_H__ */
Unlock ST M50FW002 correctly Refactor ST M50 family unlocking TODO: Unify write_lockbits_49fl00x() and unlock_block_stm50() and unlock_w39_fwh_block() and unlock_82802ab() and write_lockbits_block_49lfxxxc(). They all use exactly the same mechanism, but they don't share any code. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>