Here's a patch for the spi controllers in Intel's Baytrail & Rangeley/Avoton parts.
This core of this patch originally came from the chromium flashrom repo and was modified by Sage to support the Rangeley/Avoton parts as well.
Martin
On Fri, 30 May 2014 15:13:49 -0600 Martin Roth martin.roth@se-eng.com wrote:
- /* Enable BIOS writing */
- old = mmio_readl(ilb + 0x1c);
There are (or were) quite some unclear bits in this patch, but the line above is the most puzzling. Why is BC in the memmapped ILB region used instead of BCR at SPIBAR (SBASE) + 0xFC? The latter seems to be more similar to the old BIOS_CNTL and does contain the infamous SMM bit #5 that we try to unset for previous generations. The lock and write enable bits seem to be mirrored though.
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 */