This mainboard uses external pins for banking the ROM chip, which seems
to be impossible to do with the "internal" programmer, yet I had to clone
most of the init stuff from internal.c . Hints for a clean implementation
will be appreciated.
---
 Makefile   |    2 +-
 flash.h    |   11 ++++++
 flashrom.c |   19 ++++++++++
 t20.c      |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 139 insertions(+), 1 deletions(-)
 create mode 100644 t20.c

diff --git a/Makefile b/Makefile
index 501f65a..cdd45d1 100644
--- a/Makefile
+++ b/Makefile
@@ -101,7 +101,7 @@ CONFIG_PRINT_WIKI ?= no
 
 ifeq ($(CONFIG_INTERNAL), yes)
 FEATURE_CFLAGS += -D'INTERNAL_SUPPORT=1'
-PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o it87spi.o 
ichspi.o sb600spi.o wbsio_spi.o
+PROGRAMMER_OBJS += chipset_enable.o board_enable.o cbtable.o it87spi.o 
ichspi.o sb600spi.o t20.o wbsio_spi.o
 NEED_PCI := yes
 endif
 
diff --git a/flash.h b/flash.h
index 9a25c70..77b0d48 100644
--- a/flash.h
+++ b/flash.h
@@ -58,6 +58,9 @@ enum programmer {
 #if INTERNAL_SUPPORT == 1
        PROGRAMMER_IT87SPI,
 #endif
+#if INTERNAL_SUPPORT == 1
+       PROGRAMMER_TPT20,
+#endif
 #if FT2232_SPI_SUPPORT == 1
        PROGRAMMER_FT2232SPI,
 #endif
@@ -435,6 +438,14 @@ uint8_t drkaiser_chip_readb(const chipaddr addr);
 extern struct pcidev_status drkaiser_pcidev[];
 #endif
 
+/* t20.c */
+#if INTERNAL_SUPPORT == 1
+int t20_init(void);
+int t20_shutdown(void);
+void t20_chip_writeb(uint8_t val, chipaddr addr);
+uint8_t t20_chip_readb(const chipaddr addr);
+#endif
+
 /* satasii.c */
 #if SATASII_SUPPORT == 1
 int satasii_init(void);
diff --git a/flashrom.c b/flashrom.c
index db44c2f..7f05eeb 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -226,6 +226,25 @@ const struct programmer_entry programmer_table[] = {
        },
 #endif
 
+#if INTERNAL_SUPPORT == 1
+       {
+               .name                   = "t20",
+               .init                   = t20_init,
+               .shutdown               = t20_shutdown,
+               .map_flash_region       = fallback_map,
+               .unmap_flash_region     = fallback_unmap,
+               .chip_readb             = t20_chip_readb,
+               .chip_readw             = fallback_chip_readw,
+               .chip_readl             = fallback_chip_readl,
+               .chip_readn             = fallback_chip_readn,
+               .chip_writeb            = t20_chip_writeb,
+               .chip_writew            = fallback_chip_writew,
+               .chip_writel            = fallback_chip_writel,
+               .chip_writen            = fallback_chip_writen,
+               .delay                  = internal_delay,
+       },
+#endif
+
 #if FT2232_SPI_SUPPORT == 1
        {
                .name                   = "ft2232spi",
diff --git a/t20.c b/t20.c
new file mode 100644
index 0000000..d6841cc
--- /dev/null
+++ b/t20.c
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Michael Karcher <[email protected]>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* Base address of register IND1 in the Field IMGA in the DSDT */
+#define IMGA1_BASE 0x15EE
+
+#include "flash.h"
+
+static uint8_t *t20_base;
+
+#define MAX_COUNT 20
+
+static void imga1_mask(uint8_t index, uint8_t mask, uint8_t value)
+{
+       uint16_t temp;
+       int count = 0;
+       /* Be careful, as ACPI might use these registers too, so check
+          that the index is still OK. */
+       do {
+               OUTB(index, IMGA1_BASE);
+               temp = INW(IMGA1_BASE);
+       }
+       while ((temp & 0xff) != index && ++count < MAX_COUNT);
+       if(count == MAX_COUNT)
+       {
+               printf("error: IMGA1 index stuck at %02x\n", temp & 0xff);
+               return;
+       }
+       temp &= ~(mask << 8);
+       temp |= (value & mask) << 8;
+       OUTW(temp, IMGA1_BASE);
+}
+
+int t20_init(void)
+{
+       pacc = pci_alloc();
+       pci_init(pacc);
+       pci_scan_bus(pacc);     /* We want to get the list of devices */
+       get_io_perms();
+       /* ID of the graphics chip in T20/T21/T22. The mainboards are
+          identical in these models */
+       if (!pci_card_find(0x5333, 0x8c12, 0x1014, 0x017f))
+       {
+               msg_perr("This is not a ThinkPad T20/T21/T22\n");
+               return 1;
+       }
+       if (chipset_flash_enable() == -2) {
+               printf("WARNING: No chipset found. Flash detection "
+                      "will most likely fail.\n");
+       }
+
+       imga1_mask(0, 4, 4);    /* Enable flash writes */
+       t20_base = physmap("IBM T20 mainboard flash", 0xFFFE0000, 0x20000);
+       buses_supported = CHIP_BUSTYPE_PARALLEL;
+       return 0;
+}
+
+int t20_shutdown(void)
+{
+       physunmap(t20_base, 0x20000);
+       imga1_mask(0, 4, 4);    /* Disable flash writes */
+       release_io_perms();
+       pci_cleanup(pacc);
+       return 0;
+}
+
+static unsigned int currentbank = -1U;
+
+static void switchtobank(unsigned int banknum)
+{
+       if (banknum > 3)
+       {
+               msg_perr("Bad bank number %d\n", banknum);
+               return;
+       }
+       if(banknum != currentbank)
+               imga1_mask(0, 3, banknum);
+       currentbank = banknum;
+}
+
+void t20_chip_writeb(uint8_t val, chipaddr addr)
+{
+       switchtobank(addr >> 17);
+       mmio_writeb(val, t20_base + (addr & 0x1FFFF));
+}
+
+uint8_t t20_chip_readb(chipaddr addr)
+{
+       switchtobank(addr >> 17);
+       return mmio_readb(t20_base + (addr & 0x1FFFF));
+}
-- 
1.6.5


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to