Hi all,
This patch fixes the support for Winbond W39V040FA. I've tested the
patch and it successfully read and write the binary (with verification)
to the flash chip.
The previous code is able to read but cannot write into the chip
because the block locking registers (BLR) are not set accordingly.
Regards,
Darmawan Salihun
Index: flashchips.c
===================================================================
--- flashchips.c (revision 2744)
+++ flashchips.c (working copy)
@@ -32,6 +32,7 @@
#include "sst28sf040.h"
#include "sst49lfxxxc.h"
#include "w49f002u.h"
+#include "w39v040fa.h"
#include "sst39sf020.h"
#include "sst49lf040.h"
#include "pm49fl004.h"
@@ -105,7 +106,7 @@
{"W49V002FA", WINBOND_ID, W_49V002FA, 256, 128,
probe_jedec, erase_chip_jedec, write_49f002},
{"W39V040FA", WINBOND_ID, W_39V040FA, 512, 64*1024,
- probe_jedec, erase_chip_jedec, write_39sf020},
+ probe_jedec, erase_chip_jedec, write_39v040fa},
{"W39V040A", WINBOND_ID, W_39V040A, 512, 64*1024,
probe_jedec, erase_chip_jedec, write_39sf020},
{"W39V040B", WINBOND_ID, W_39V040B, 512, 64*1024,
Index: Makefile
===================================================================
--- Makefile (revision 2744)
+++ Makefile (working copy)
@@ -24,7 +24,7 @@
am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \
82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \
sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
- sharplhf00l04.o
+ sharplhf00l04.o w39v040fa.o
all: pciutils dep $(PROGRAM)
Index: w39v040fa.c
===================================================================
--- w39v040fa.c (revision 0)
+++ w39v040fa.c (revision 0)
@@ -0,0 +1,109 @@
+/*
+ * w39v040fa.c: driver for Winbond W39V040FAx flash models.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Reference:
+ * Winbond W39V040FA data sheets
+ *
+ */
+#include <sys/mman.h>
+#include <stdio.h>
+
+#include "flash.h"
+#include "jedec.h"
+#include "debug.h"
+
+enum {
+ BLOCKING_REGS_PHY_RANGE = 0x80000,
+ BLOCKING_REGS_PHY_BASE = 0xFFB80000,
+};
+
+static volatile uint8_t* unprotect_39v040fa(void)
+{
+ uint8_t i, byte_val;
+ volatile uint8_t *block_regs_base;
+
+ block_regs_base = (volatile uint8_t*) mmap( 0, BLOCKING_REGS_PHY_RANGE, PROT_WRITE | PROT_READ,
+ MAP_SHARED, fd_mem, (off_t)BLOCKING_REGS_PHY_BASE );
+ if (block_regs_base == NULL) {
+ perror("Error: Unable to map Winbond w39v040fa blocking registers!\n");
+ return NULL;
+ }
+
+ //
+ // Unprotect the BIOS chip address range
+ //
+ for( i = 0; i < 8 ; i++ )
+ {
+ byte_val = *(volatile uint8_t*)(block_regs_base + 2 + i*0x10000);
+ usleep(10);
+ byte_val &= 0xF8; // Enable full access to the chip
+ *(volatile uint8_t*)(block_regs_base + 2 + i*0x10000) = byte_val;
+ usleep(10);
+ }
+
+ return block_regs_base;
+}
+
+static void protect_39v040fa(volatile uint8_t * reg_base)
+{
+ //
+ // Protect the BIOS chip address range
+ //
+ uint8_t i, byte_val;
+ volatile uint8_t *block_regs_base = reg_base;
+
+ for( i = 0; i < 8 ; i++ )
+ {
+ byte_val = *(volatile uint8_t*)(block_regs_base + 2 + i*0x10000);
+ usleep(10);
+ byte_val |= 1; // Prohibited to write in the block where set
+ *(volatile uint8_t*)(block_regs_base + 2 + i*0x10000) = byte_val;
+ usleep(10);
+ }
+
+ munmap((void*) reg_base, BLOCKING_REGS_PHY_RANGE);
+}
+
+int write_39v040fa(struct flashchip *flash, uint8_t *buf)
+{
+ int i;
+ int total_size = flash->total_size * 1024;
+ int page_size = flash->page_size;
+ volatile uint8_t *bios = flash->virtual_memory;
+ volatile uint8_t * reg_base;
+
+ reg_base = unprotect_39v040fa();
+ erase_chip_jedec(flash);
+
+ printf("Programming Page: ");
+ for (i = 0; i < total_size / page_size; i++) {
+ /* write to the sector */
+ printf("%04d at address: 0x%08x", i, i * page_size);
+ write_sector_jedec(bios, buf + i * page_size, bios + i * page_size, page_size);
+ printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
+ fflush(stdout);
+ }
+ printf("\n");
+
+ if(NULL != reg_base)
+ {
+ protect_39v040fa(reg_base);
+ }
+
+ return (0);
+}
Index: w39v040fa.h
===================================================================
--- w39v040fa.h (revision 0)
+++ w39v040fa.h (revision 0)
@@ -0,0 +1,6 @@
+#ifndef __W39V040FA_H__
+#define __W39V040FA_H__ 1
+
+extern int write_39v040fa(struct flashchip *flash, uint8_t *buf);
+
+#endif /* !__W39V040FA_H__ */
--
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios