This PCI PATA controller can use 3V parallel flash upto 128kB.
My card was identified as: PCI 1283:8212, subsystem 1283:0001.
and labelled as: Innovision Multimedia LTD. EIO ATA133 RAID (DM-8401 Ver A)
This particular card did not require setting of any GPIO signals to enable flash writing. My card has Pm39LV512 in PLCC32 package without socket.
Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com
Index: flashrom-it8212f/Makefile =================================================================== --- flashrom-it8212f/Makefile (revision 1539) +++ flashrom-it8212f/Makefile (working copy) @@ -177,7 +177,12 @@ else override CONFIG_SATAMV = no endif +ifeq ($(CONFIG_IT8212), yes) +UNSUPPORTED_FEATURES += CONFIG_IT8212=yes +else +override CONFIG_IT8212 = no endif +endif
ifeq ($(TARGET_OS), libpayload) CPPFLAGS += -DSTANDALONE @@ -344,6 +349,9 @@ # Enable Linux spidev interface by default. We disable it on non-Linux targets. CONFIG_LINUX_SPI ?= yes
+# Always enable ITE IT8212F PATA controllers for now. +CONFIG_IT8212 ?= yes + # Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -503,6 +511,12 @@ PROGRAMMER_OBJS += linux_spi.o endif
+ifeq ($(CONFIG_IT8212), yes) +FEATURE_CFLAGS += -D'CONFIG_IT8212=1' +PROGRAMMER_OBJS += it8212.o +NEED_PCI := yes +endif + ifeq ($(NEED_SERIAL), yes) LIB_OBJS += serial.o endif Index: flashrom-it8212f/print_wiki.c =================================================================== --- flashrom-it8212f/print_wiki.c (revision 1539) +++ flashrom-it8212f/print_wiki.c (working copy) @@ -338,6 +338,9 @@ #if CONFIG_SATAMV == 1 print_supported_pcidevs_wiki(satas_mv); #endif +#if CONFIG_IT8212 == 1 + print_supported_pcidevs_wiki(ata_it82); +#endif printf("\n|}\n"); }
Index: flashrom-it8212f/it8212.c =================================================================== --- flashrom-it8212f/it8212.c (revision 0) +++ flashrom-it8212f/it8212.c (revision 0) @@ -0,0 +1,110 @@ +/* + * This file is part of the flashrom project. + * + * 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 + * the Free Software Foundation; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdlib.h> +#include "flash.h" +#include "programmer.h" + +static uint8_t *it8212_bar; +static uint8_t it8212_rom_enable = 0; + +#define PCI_VENDOR_ID_ITE 0x1283 + +const struct pcidev_status ata_it82[] = { + {PCI_VENDOR_ID_ITE, 0x8212, OK, "ITE", "8212F PATA RAID"}, + {}, +}; + +#define IT8212_MEMMAP_SIZE (128 * 1024) +#define IT8212_MEMMAP_MASK (IT8212_MEMMAP_SIZE - 1) + +static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, + chipaddr addr); +static uint8_t it8212_chip_readb(const struct flashctx *flash, + const chipaddr addr); +static const struct par_programmer par_programmer_it8212 = { + .chip_readb = it8212_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = it8212_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +static int it8212_shutdown(void *data) +{ + if (! it8212_rom_enable) { + uintptr_t addr = pci_read_long(pcidev_dev, PCI_ROM_ADDRESS); + pci_write_long(pcidev_dev, PCI_ROM_ADDRESS, addr & ~0x01); + } + physunmap(it8212_bar, IT8212_MEMMAP_SIZE); + pci_cleanup(pacc); + release_io_perms(); + return 0; +} + +int it8212_init(void) +{ + uintptr_t addr; + + /* Needed only for PCI accesses on some platforms. + * FIXME: Refactor that into get_mem_perms/get_io_perms/get_pci_perms? + */ + get_io_perms(); + + /* No need to check for errors, pcidev_init() will not return in case + * of errors. + */ + addr = pcidev_init(PCI_ROM_ADDRESS, ata_it82); + + it8212_bar = physmap("IT8212F flash", addr, IT8212_MEMMAP_SIZE); + if (it8212_bar == ERROR_PTR) + goto error_out_unmap; + if (register_shutdown(it8212_shutdown, NULL)) + return 1; + + /* To restore ROM BAR enable once we are done. */ + it8212_rom_enable = addr & 0x01; + if (! it8212_rom_enable) + pci_write_long(pcidev_dev, PCI_ROM_ADDRESS, addr | 0x01); + + max_rom_decode.parallel = IT8212_MEMMAP_SIZE; + register_par_programmer(&par_programmer_it8212, BUS_PARALLEL); + return 0; + +error_out_unmap: + physunmap(it8212_bar, IT8212_MEMMAP_SIZE); + pci_cleanup(pacc); + release_io_perms(); + return 1; +} + +static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, + chipaddr addr) +{ + pci_mmio_writeb(val, it8212_bar + (addr & IT8212_MEMMAP_MASK)); +} + +static uint8_t it8212_chip_readb(const struct flashctx *flash, + const chipaddr addr) +{ + return pci_mmio_readb(it8212_bar + (addr & IT8212_MEMMAP_MASK)); +} Index: flashrom-it8212f/flashrom.c =================================================================== --- flashrom-it8212f/flashrom.c (revision 1539) +++ flashrom-it8212f/flashrom.c (working copy) @@ -261,6 +261,16 @@ }, #endif
+#if CONFIG_IT8212 == 1 + { + .name = "it8212", + .init = it8212_init, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, + .delay = internal_delay, + }, +#endif + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-it8212f/programmer.h =================================================================== --- flashrom-it8212f/programmer.h (revision 1539) +++ flashrom-it8212f/programmer.h (working copy) @@ -87,6 +87,9 @@ #if CONFIG_LINUX_SPI == 1 PROGRAMMER_LINUX_SPI, #endif +#if CONFIG_IT8212 == 1 + PROGRAMMER_IT8212, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -456,6 +459,12 @@ int linux_spi_init(void); #endif
+/* it8212.c */ +#if CONFIG_IT8212 == 1 +int it8212_init(void); +extern const struct pcidev_status ata_it82[]; +#endif + /* dediprog.c */ #if CONFIG_DEDIPROG == 1 int dediprog_init(void); Index: flashrom-it8212f/print.c =================================================================== --- flashrom-it8212f/print.c (revision 1539) +++ flashrom-it8212f/print.c (working copy) @@ -538,6 +538,11 @@ programmer_table[PROGRAMMER_LINUX_SPI].name); msg_ginfo("Device files /dev/spidev*.*\n"); #endif +#if CONFIG_IT8212 == 1 + msg_ginfo("\nSupported devices for the %s programmer:\n", + programmer_table[PROGRAMMER_IT8212].name); + print_supported_pcidevs(ata_it82); +#endif }
#if CONFIG_INTERNAL == 1