The core of this patch to support Bay Trail originally came from the Chromiumos flashrom repo and was modified by Sage to support the Rangeley/Avoton parts as well. Because that was not complicated enough already Stefan Tauner refactored everything and integrated Chromiumos' support for Wildcat as well.
Signed-off-by: Duncan Laurie dlaurie@chromium.org Signed-off-by: Stefan Tauner stefan.tauner@alumni.tuwien.ac.at ---
Martin: please sign off this patch in a reply as well because you forgot to sign off previouslly.
I have worked pretty hard to reuse much of the existing code and I think that worked out quite well. I had to dig through quite some code and datasheets and I'd rather see this tested on real hardware please. Anyone with affected hardware please test this patch!
chipset_enable.c | 259 ++++++++++++++++++++++++++++++++++++++++++------------- ichspi.c | 14 +-- programmer.h | 2 + 3 files changed, 209 insertions(+), 66 deletions(-)
diff --git a/chipset_enable.c b/chipset_enable.c index ec3c12c..d1976ba 100644 --- a/chipset_enable.c +++ b/chipset_enable.c @@ -260,9 +260,13 @@ static int enable_flash_piix4(struct pci_dev *dev, const char *name) return 0; }
-/* Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom +/* Handle BIOS_CNTL (aka. BCR). Disable locks and enable writes. The register can either be in PCI config space + * at the offset given by 'bios_cntl' or at the memory-mapped address 'addr'. + * + * Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom * chipsets/SoCs it is even 32b, but just treating it as 8 bit wide seems to work fine in practice. */ -static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) +static int enable_flash_ich_bios_cntl_common(enum ich_chipset ich_generation, void *addr, + struct pci_dev *dev, uint8_t bios_cntl) { uint8_t old, new, wanted;
@@ -273,8 +277,8 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_ case CHIPSET_ICH: case CHIPSET_ICH2345: break; - /* Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to what - * other SPI-capable chipsets have at DCh. + /* Some Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to + * what other SPI-capable chipsets have at DCh. Others like Bay Trail use a memmapped register. * The Tunnel Creek datasheet contains a lot of details about the SPI controller, among other things it * mentions that the prefetching and caching does only happen for direct memory reads. * Therefore - at least for Tunnel Creek - it should not matter to flashrom because we use the @@ -285,9 +289,13 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_ old = pci_read_byte(dev, bios_cntl + 1); msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis"); break; + case CHIPSET_BAYTRAIL: case CHIPSET_ICH7: default: /* Future version might behave the same */ - old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3; + if (ich_generation == CHIPSET_BAYTRAIL) + old = (mmio_readl(addr) >> 2) & 0x3; + else + old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3; msg_pdbg("SPI Read Configuration: "); if (old == 3) msg_pdbg("invalid prefetching/caching settings, "); @@ -297,7 +305,11 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_ (old & 0x1) ? "dis" : "en"); }
- wanted = old = pci_read_byte(dev, bios_cntl); + if (ich_generation == CHIPSET_BAYTRAIL) + wanted = old = mmio_readl(addr); + else + wanted = old = pci_read_byte(dev, bios_cntl); + /* * Quote from the 6 Series datasheet (Document Number: 324645-004): * "Bit 5: SMM BIOS Write Protect Disable (SMM_BWP) @@ -327,8 +339,13 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
/* Only write the register if it's necessary */ if (wanted != old) { - rpci_write_byte(dev, bios_cntl, wanted); - new = pci_read_byte(dev, bios_cntl); + if (ich_generation == CHIPSET_BAYTRAIL) { + rmmio_writel(wanted, addr); + new = mmio_readl(addr); + } else { + rpci_write_byte(dev, bios_cntl, wanted); + new = pci_read_byte(dev, bios_cntl); + } } else new = old;
@@ -349,10 +366,22 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_ return 0; }
+static int enable_flash_ich_bios_cntl_config_space(struct pci_dev *dev, enum ich_chipset ich_generation, + uint8_t bios_cntl) +{ + return enable_flash_ich_bios_cntl_common(ich_generation, NULL, dev, bios_cntl); +} + +static int enable_flash_ich_bios_cntl_memmapped(enum ich_chipset ich_generation, void *addr) +{ + return enable_flash_ich_bios_cntl_common(ich_generation, addr, NULL, 0); +} + static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich_generation) { uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */ bool implemented = 0; + void *ilb = NULL; /* Only for Baytrail */ switch (ich_generation) { case CHIPSET_ICH: /* FIXME: Unlike later chipsets, ICH and ICH-0 do only support mapping of the top-most 4MB @@ -373,6 +402,18 @@ static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich case CHIPSET_CENTERTON: /* FIXME: Similar to above FWH_DEC_EN (D4h) and FWH_SEL (D0h). */ break; + case CHIPSET_BAYTRAIL: { + uint32_t ilb_base = pci_read_long(dev, 0x50) & 0xfffffe00; /* bits 31:9 */ + if (ilb_base == 0) { + msg_perr("Error: Invalid ILB_BASE_ADDRESS\n"); + return ERROR_FATAL; + } + ilb = rphysmap("BYT IBASE", ilb_base, 512); + fwh_sel1 = 0x18; + fwh_dec_en_lo = 0xd8; + fwh_dec_en_hi = 0xd9; + break; + } case CHIPSET_ICH6: case CHIPSET_ICH7: default: /* Future version might behave the same */ @@ -397,17 +438,27 @@ static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich msg_perr("Error: fwh_idsel= specified, but value could not be converted.\n"); goto idsel_garbage_out; } - if (fwh_idsel & 0xffff000000000000ULL) { + uint64_t fwh_mask = 0xffffffff; + if (fwh_sel2 > 0) + fwh_mask |= (0xffffUL << 32); + if (fwh_idsel & ~fwh_mask) { msg_perr("Error: fwh_idsel= specified, but value had unused bits set.\n"); goto idsel_garbage_out; } - uint64_t fwh_idsel_old = pci_read_long(dev, fwh_sel1); - fwh_idsel_old <<= 16; - fwh_idsel_old |= pci_read_word(dev, fwh_sel2); - msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.", + uint64_t fwh_idsel_old; + if (ich_generation == CHIPSET_BAYTRAIL) { + fwh_idsel_old = mmio_readl(ilb + fwh_sel1); + rmmio_writel(fwh_idsel, ilb + fwh_sel1); + } else { + fwh_idsel_old = pci_read_long(dev, fwh_sel1) << 16; + rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff); + if (fwh_sel2 > 0) { + fwh_idsel_old |= pci_read_word(dev, fwh_sel2); + rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff); + } + } + msg_pdbg("Setting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.\n", fwh_idsel_old, fwh_idsel); - rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff); - rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff); /* FIXME: Decode settings are not changed. */ } else if (idsel) { msg_perr("Error: fwh_idsel= specified, but no value given.\n"); @@ -418,7 +469,7 @@ idsel_garbage_out: free(idsel);
if (!implemented) { - msg_pdbg2("FWH IDSEL handling is not implemented on this chipset."); + msg_pdbg2("FWH IDSEL handling is not implemented on this chipset.\n"); return 0; }
@@ -429,12 +480,17 @@ idsel_garbage_out: */ int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0; bool contiguous = 1; - uint32_t fwh_conf = pci_read_long(dev, fwh_sel1); + uint32_t fwh_conf; + if (ich_generation == CHIPSET_BAYTRAIL) + fwh_conf = mmio_readl(ilb + fwh_sel1); + else + fwh_conf = pci_read_long(dev, fwh_sel1); + int i; /* FWH_SEL1 */ for (i = 7; i >= 0; i--) { int tmp = (fwh_conf >> (i * 4)) & 0xf; - msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x", + msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n", (0x1ff8 + i) * 0x80000, (0x1ff0 + i) * 0x80000, tmp); @@ -444,28 +500,31 @@ idsel_garbage_out: contiguous = 0; } } - /* FWH_SEL2 */ - fwh_conf = pci_read_word(dev, fwh_sel2); - for (i = 3; i >= 0; i--) { - int tmp = (fwh_conf >> (i * 4)) & 0xf; - msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x", - (0xff4 + i) * 0x100000, - (0xff0 + i) * 0x100000, - tmp); - if ((tmp == 0) && contiguous) { - max_decode_fwh_idsel = (8 - i) * 0x100000; - } else { - contiguous = 0; + + if (fwh_sel2 > 0) { + /* FWH_SEL2 */ + fwh_conf = pci_read_word(dev, fwh_sel2); + for (i = 3; i >= 0; i--) { + int tmp = (fwh_conf >> (i * 4)) & 0xf; + msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n", + (0xff4 + i) * 0x100000, + (0xff0 + i) * 0x100000, + tmp); + if ((tmp == 0) && contiguous) { + max_decode_fwh_idsel = (8 - i) * 0x100000; + } else { + contiguous = 0; + } } + contiguous = 1; } - contiguous = 1; /* FWH_DEC_EN1 */ fwh_conf = pci_read_byte(dev, fwh_dec_en_hi); fwh_conf <<= 8; fwh_conf |= pci_read_byte(dev, fwh_dec_en_lo); for (i = 7; i >= 0; i--) { int tmp = (fwh_conf >> (i + 0x8)) & 0x1; - msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled", + msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n", (0x1ff8 + i) * 0x80000, (0x1ff0 + i) * 0x80000, tmp ? "en" : "dis"); @@ -477,7 +536,7 @@ idsel_garbage_out: } for (i = 3; i >= 0; i--) { int tmp = (fwh_conf >> i) & 0x1; - msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled", + msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n", (0xff4 + i) * 0x100000, (0xff0 + i) * 0x100000, tmp ? "en" : "dis"); @@ -488,7 +547,7 @@ idsel_garbage_out: } } max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode); - msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh); + msg_pdbg("Maximum FWH chip size: 0x%x bytes\n", max_rom_decode.fwh);
return 0; } @@ -502,7 +561,7 @@ static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_genera return err;
internal_buses_supported = BUS_FWH; - return enable_flash_ich_bios_cntl(dev, ich_generation, bios_cntl); + return enable_flash_ich_bios_cntl_config_space(dev, ich_generation, bios_cntl); }
static int enable_flash_ich0(struct pci_dev *dev, const char *name) @@ -525,14 +584,18 @@ static int enable_flash_poulsbo(struct pci_dev *dev, const char *name) return enable_flash_ich_fwh(dev, CHIPSET_POULSBO, 0xd8); }
-static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) +static void enable_flash_ich_handle_gcs(struct pci_dev *dev, enum ich_chipset ich_generation, uint32_t gcs, bool top_swap) { + msg_pdbg("GCS = 0x%x: ", gcs); + + msg_pdbg("BIOS Interface Lock-Down: %sabled, ", (gcs & 0x1) ? "en" : "dis"); + static const char *const straps_names_EP80579[] = { "SPI", "reserved", "reserved", "LPC" }; static const char *const straps_names_ich7_nm10[] = { "reserved", "SPI", "PCI", "LPC" }; static const char *const straps_names_tunnel_creek[] = { "SPI", "LPC" }; static const char *const straps_names_ich8910[] = { "SPI", "SPI", "PCI", "LPC" }; static const char *const straps_names_pch567[] = { "LPC", "reserved", "PCI", "SPI" }; - static const char *const straps_names_pch8[] = { "LPC", "reserved", "reserved", "SPI" }; + static const char *const straps_names_pch89_baytrail[] = { "LPC", "reserved", "reserved", "SPI" }; static const char *const straps_names_pch8_lp[] = { "SPI", "LPC" }; static const char *const straps_names_unknown[] = { "unknown", "unknown", "unknown", "unknown" };
@@ -561,7 +624,9 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera straps_names = straps_names_pch567; break; case CHIPSET_8_SERIES_LYNX_POINT: - straps_names = straps_names_pch8; + case CHIPSET_9_SERIES_WILDCAT_POINT: + case CHIPSET_BAYTRAIL: + straps_names = straps_names_pch89_baytrail; break; case CHIPSET_8_SERIES_LYNX_POINT_LP: straps_names = straps_names_pch8_lp; @@ -576,40 +641,40 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera break; }
- /* Get physical address of Root Complex Register Block */ - uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000; - msg_pdbg("Root Complex Register Block address = 0x%x\n", rcra); - - /* Map RCBA to virtual memory */ - void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000); - if (rcrb == ERROR_PTR) - return ERROR_FATAL; - - uint32_t gcs = mmio_readl(rcrb + 0x3410); - msg_pdbg("GCS = 0x%x: ", gcs); - msg_pdbg("BIOS Interface Lock-Down: %sabled, ", (gcs & 0x1) ? "en" : "dis"); - uint8_t bbs; switch (ich_generation) { case CHIPSET_TUNNEL_CREEK: bbs = (gcs >> 1) & 0x1; break; case CHIPSET_8_SERIES_LYNX_POINT_LP: - case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet - /* Lynx Point LP uses a single bit for GCS */ + /* Lynx Point LP uses a single bit for BBS */ bbs = (gcs >> 10) & 0x1; break; default: - /* Older chipsets use two bits for GCS */ + /* Other chipsets use two bits for BBS */ bbs = (gcs >> 10) & 0x3; break; } msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]);
- if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON) { - uint8_t buc = mmio_readb(rcrb + 0x3414); - msg_pdbg("Top Swap : %s\n", (buc & 1) ? "enabled (A16(+) inverted)" : "not enabled"); - } + /* Centerton has its TS bit in [GPE0BLK] + 0x30 while the exact location for Tunnel Creek is unknown. */ + if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON) + msg_pdbg("Top Swap : %s\n", (top_swap) ? "enabled (A16(+) inverted)" : "not enabled"); +} + +static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) +{ + + /* Get physical address of Root Complex Register Block */ + uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000; + msg_pdbg("Root Complex Register Block address = 0x%x\n", rcra); + + /* Map RCBA to virtual memory */ + void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000); + if (rcrb == ERROR_PTR) + return ERROR_FATAL; + + enable_flash_ich_handle_gcs(dev, ich_generation, mmio_readl(rcrb + 0x3410), mmio_readb(rcrb + 0x3414));
/* Handle FWH-related parameters and initialization */ int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl); @@ -619,6 +684,7 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera /* SPIBAR is at RCRB+0x3020 for ICH[78], Tunnel Creek and Centerton, and RCRB+0x3800 for ICH9. */ uint16_t spibar_offset; switch (ich_generation) { + case CHIPSET_BAYTRAIL: case CHIPSET_ICH_UNKNOWN: return ERROR_FATAL; case CHIPSET_ICH7: @@ -712,6 +778,63 @@ static int enable_flash_pch8_wb(struct pci_dev *dev, const char *name) return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc); }
+/* Wildcat Point */ +static int enable_flash_pch9(struct pci_dev *dev, const char *name) +{ + return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc); +} + +/* Silvermont architecture: Bay Trail(-T/-I), Avoton/Rangeley. + * These have a distinctly different behavior compared to other Intel chipsets and hence are handled separately. + * + * Differences include: + * - RCBA at LPC config 0xF0 too but mapped range is only 4 B long instead of 16 kB. + * - GCS at [RCRB] + 0 (instead of [RCRB] + 0x3410). + * - TS (Top Swap) in GCS (instead of [RCRB] + 0x3414). + * - SPIBAR (coined SBASE) at LPC config 0x54 (instead of [RCRB] + 0x3800). + * - BIOS_CNTL (coined BCR) at [SPIBAR] + 0xFC (instead of LPC config 0xDC). + */ +static int enable_flash_silvermont(struct pci_dev *dev, const char *name) +{ + enum ich_chipset ich_generation = CHIPSET_BAYTRAIL; + + /* Get physical address of Root Complex Register Block */ + uint32_t rcba = pci_read_long(dev, 0xf0) & 0xfffffc00; + msg_pdbg("Root Complex Register Block address = 0x%x\n", rcba); + + /* Handle GCS (in RCRB) */ + void *rcrb = physmap("BYT RCRB", rcba, 4); + uint32_t gcs = mmio_readl(rcrb + 0); + enable_flash_ich_handle_gcs(dev, ich_generation, gcs, gcs & 0x2); + physunmap(rcrb, 4); + + /* Handle fwh_idsel parameter */ + int ret = enable_flash_ich_fwh_decode(dev, ich_generation); + if (ret != ERROR_FATAL) + return ret; + + internal_buses_supported = BUS_FWH; + + /* Get physical address of SPI Base Address and map it */ + uint32_t sbase = pci_read_long(dev, 0x54) & 0xfffffe00; + msg_pdbg("SPI_BASE_ADDRESS = 0x%x\n", sbase); + void *spibar = rphysmap("BYT SBASE", sbase, 512); /* Last defined address on Bay Trail is 0x100 */ + + /* Enable Flash Writes. + * Silvermont-based: BCR at SBASE + 0xFC (some bits of BCR are also accessible via BC at IBASE + 0x1C). + */ + enable_flash_ich_bios_cntl_memmapped(ich_generation, spibar + 0xFC); + + int ret_spi = ich_init_spi(dev, spibar, ich_generation); + if (ret_spi == ERROR_FATAL) + return ret_spi; + + if (ret || ret_spi) + return ERROR_NONFATAL; + + return 0; +} + static int via_no_byte_merge(struct pci_dev *dev, const char *name) { uint8_t val; @@ -1468,6 +1591,10 @@ const struct penable chipset_enables[] = { {0x1166, 0x0205, OK, "Broadcom", "HT-1000", enable_flash_ht1000}, {0x17f3, 0x6030, OK, "RDC", "R8610/R3210", enable_flash_rdc_r8610}, {0x8086, 0x0c60, NT, "Intel", "S12x0", enable_flash_s12x0}, + {0x8086, 0x0f1c, NT, "Intel", "Bay Trail", enable_flash_silvermont}, + {0x8086, 0x0f1d, NT, "Intel", "Bay Trail", enable_flash_silvermont}, + {0x8086, 0x0f1e, NT, "Intel", "Bay Trail", enable_flash_silvermont}, + {0x8086, 0x0f1f, NT, "Intel", "Bay Trail", enable_flash_silvermont}, {0x8086, 0x122e, OK, "Intel", "PIIX", enable_flash_piix4}, {0x8086, 0x1234, NT, "Intel", "MPIIX", enable_flash_piix4}, {0x8086, 0x1c44, DEP, "Intel", "Z68", enable_flash_pch6}, @@ -1502,7 +1629,11 @@ const struct penable chipset_enables[] = { {0x8086, 0x1e5d, NT, "Intel", "HM75", enable_flash_pch7}, {0x8086, 0x1e5e, NT, "Intel", "HM70", enable_flash_pch7}, {0x8086, 0x1e5f, DEP, "Intel", "NM70", enable_flash_pch7}, - {0x8086, 0x2310, NT, "Intel", "DH89xxCC", enable_flash_pch7}, + {0x8086, 0x1f38, NT, "Intel", "Avoton/Rangeley", enable_flash_silvermont}, + {0x8086, 0x1f39, NT, "Intel", "Avoton/Rangeley", enable_flash_silvermont}, + {0x8086, 0x1f3a, NT, "Intel", "Avoton/Rangeley", enable_flash_silvermont}, + {0x8086, 0x1f3b, NT, "Intel", "Avoton/Rangeley", enable_flash_silvermont}, + {0x8086, 0x2310, NT, "Intel", "DH89xxCC (Cave Creek)", enable_flash_pch7}, {0x8086, 0x2390, NT, "Intel", "Coleto Creek", enable_flash_pch7}, {0x8086, 0x2410, OK, "Intel", "ICH", enable_flash_ich0}, {0x8086, 0x2420, OK, "Intel", "ICH0", enable_flash_ich0}, @@ -1564,7 +1695,7 @@ const struct penable chipset_enables[] = { {0x8086, 0x7110, OK, "Intel", "PIIX4/4E/4M", enable_flash_piix4}, {0x8086, 0x7198, OK, "Intel", "440MX", enable_flash_piix4}, {0x8086, 0x8119, OK, "Intel", "SCH Poulsbo", enable_flash_poulsbo}, - {0x8086, 0x8186, OK, "Intel", "Atom E6xx(T)/Tunnel Creek", enable_flash_tunnelcreek}, + {0x8086, 0x8186, OK, "Intel", "Atom E6xx(T) (Tunnel Creek)", enable_flash_tunnelcreek}, {0x8086, 0x8c40, NT, "Intel", "Lynx Point", enable_flash_pch8}, {0x8086, 0x8c41, NT, "Intel", "Lynx Point Mobile Eng. Sample", enable_flash_pch8}, {0x8086, 0x8c42, NT, "Intel", "Lynx Point Desktop Eng. Sample",enable_flash_pch8}, @@ -1633,6 +1764,14 @@ const struct penable chipset_enables[] = { {0x8086, 0x8d5d, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, {0x8086, 0x8d5e, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, {0x8086, 0x8d5f, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, + {0x8086, 0x9cc1, NT, "Intel", "Haswell U Sample", enable_flash_pch9}, + {0x8086, 0x9cc2, NT, "Intel", "Broadwell U Sample", enable_flash_pch9}, + {0x8086, 0x9cc3, NT, "Intel", "Broadwell U Premium", enable_flash_pch9}, + {0x8086, 0x9cc5, NT, "Intel", "Broadwell U Base", enable_flash_pch9}, + {0x8086, 0x9cc6, NT, "Intel", "Broadwell Y Sample", enable_flash_pch9}, + {0x8086, 0x9cc7, NT, "Intel", "Broadwell Y Premium", enable_flash_pch9}, + {0x8086, 0x9cc9, NT, "Intel", "Broadwell Y Base", enable_flash_pch9}, + {0x8086, 0x9ccb, NT, "Intel", "Broadwell H", enable_flash_pch9}, #endif {0}, }; diff --git a/ichspi.c b/ichspi.c index 190ad5a..1bce06f 100644 --- a/ichspi.c +++ b/ichspi.c @@ -612,7 +612,8 @@ static void ich_set_bbar(uint32_t min_addr) bbar_off = 0x50; break; case CHIPSET_ICH8: - msg_perr("BBAR offset is unknown on ICH8!\n"); + case CHIPSET_BAYTRAIL: + msg_pdbg("BBAR offset is unknown on ICH8!\n"); return; case CHIPSET_ICH9: default: /* Future version might behave the same */ @@ -1731,9 +1732,12 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) msg_pdbg("VSCC: "); prettyprint_ich_reg_vscc(tmp, MSG_DEBUG); } else { - ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR); - msg_pdbg("0xA0: 0x%08x (BBAR)\n", - ichspi_bbar); + if (ich_generation != CHIPSET_BAYTRAIL && desc_valid) { + ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR); + msg_pdbg("0xA0: 0x%08x (BBAR)\n", + ichspi_bbar); + ich_set_bbar(0); + }
if (desc_valid) { tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC); @@ -1749,10 +1753,8 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) tmp = mmio_readl(ich_spibar + ICH9_REG_FPB); msg_pdbg("0xD0: 0x%08x (FPB)\n", tmp); } - ich_set_bbar(0); }
- msg_pdbg("\n"); if (desc_valid) { if (read_ich_descriptors_via_fdo(ich_spibar, &desc) == ICH_RET_OK) diff --git a/programmer.h b/programmer.h index b0df2ba..d6ab254 100644 --- a/programmer.h +++ b/programmer.h @@ -594,6 +594,8 @@ enum ich_chipset { CHIPSET_8_SERIES_LYNX_POINT, CHIPSET_8_SERIES_LYNX_POINT_LP, CHIPSET_8_SERIES_WELLSBURG, + CHIPSET_9_SERIES_WILDCAT_POINT, + CHIPSET_BAYTRAIL, /* Actually all with Silvermont architecture: Bay Trail, Avoton/Rangeley */ };
/* ichspi.c */