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
Index: chipset_enable.c
===================================================================
--- chipset_enable.c (revision 1806)
+++ chipset_enable.c (working copy)
@@ -282,6 +282,7 @@
case CHIPSET_TUNNEL_CREEK:
case CHIPSET_POULSBO:
case CHIPSET_CENTERTON:
+ case CHIPSET_BAYTRAIL:
old = pci_read_byte(dev, bios_cntl + 1);
msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis");
break;
@@ -493,6 +494,132 @@
return 0;
}
+static int enable_flash_byt(struct pci_dev *dev, const char *name)
+{
+ uint32_t old, new, wanted, fwh_conf;
+ int i, tmp;
+ char *idsel = NULL;
+ int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0;
+ int contiguous = 1;
+ uint32_t ilb_base;
+ void *ilb;
+
+ /* Determine iLB base address */
+ ilb_base = pci_read_long(dev, 0x50);
+ ilb_base &= 0xfffffe00; /* bits 31:9 */
+ if (ilb_base == 0) {
+ msg_perr("Error: Invalid ILB_BASE_ADDRESS\n");
+ return ERROR_FATAL;
+ }
+ ilb = physmap("BYT IBASE", ilb_base, 512);
+
+ idsel = extract_programmer_param("fwh_idsel");
+ if (idsel && strlen(idsel)) {
+ uint64_t fwh_idsel_old, fwh_idsel;
+ errno = 0;
+ /* Base 16, nothing else makes sense. */
+ fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16);
+ if (errno) {
+ msg_perr("Error: fwh_idsel= specified, but value could "
+ "not be converted.\n");
+ free(idsel);
+ return ERROR_FATAL;
+ }
+ if (fwh_idsel & 0xffff000000000000ULL) {
+ msg_perr("Error: fwh_idsel= specified, but value had "
+ "unused bits set.\n");
+ free(idsel);
+ return ERROR_FATAL;
+ }
+ fwh_idsel_old = mmio_readl(ilb + 0x18);
+ msg_pdbg("\nSetting IDSEL from 0x%08" PRIx64 " to "
+ "0x%08" PRIx64 " for top 16 MB.", fwh_idsel_old,
+ fwh_idsel);
+ rmmio_writel(fwh_idsel, ilb + 0x18);
+ /* FIXME: Decode settings are not changed. */
+ } else if (idsel) {
+ msg_perr("Error: fwh_idsel= specified, but no value given.\n");
+ free(idsel);
+ return ERROR_FATAL;
+ }
+ free(idsel);
+
+ /* Ignore all legacy ranges below 1 MB.
+ * We currently only support flashing the chip which responds to
+ * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations
+ * have to be adjusted.
+ */
+ /* FS - FWH ID Select */
+ fwh_conf = mmio_readl(ilb + 0x18);
+ for (i = 7; i >= 0; i--) {
+ tmp = (fwh_conf >> (i * 4)) & 0xf;
+ msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
+ (0x1ff8 + i) * 0x80000,
+ (0x1ff0 + i) * 0x80000,
+ tmp);
+ if ((tmp == 0) && contiguous) {
+ max_decode_fwh_idsel = (8 - i) * 0x80000;
+ } else {
+ contiguous = 0;
+ }
+ }
+ contiguous = 1;
+ /* PCIE_REG_BIOS_DECODE_EN */
+ fwh_conf = pci_read_word(dev, 0xd8);
+ for (i = 7; i >= 0; i--) {
+ tmp = (fwh_conf >> (i + 0x8)) & 0x1;
+ msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
+ (0x1ff8 + i) * 0x80000,
+ (0x1ff0 + i) * 0x80000,
+ tmp ? "en" : "dis");
+ if ((tmp == 1) && contiguous) {
+ max_decode_fwh_decode = (8 - i) * 0x80000;
+ } else {
+ contiguous = 0;
+ }
+ }
+ for (i = 3; i >= 0; i--) {
+ tmp = (fwh_conf >> i) & 0x1;
+ msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
+ (0xff4 + i) * 0x100000,
+ (0xff0 + i) * 0x100000,
+ tmp ? "en" : "dis");
+ if ((tmp == 1) && contiguous) {
+ max_decode_fwh_decode = (8 - i) * 0x100000;
+ } else {
+ contiguous = 0;
+ }
+ }
+ 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);
+
+ /* Enable BIOS writing */
+ old = mmio_readl(ilb + 0x1c);
+ wanted = old;
+
+ msg_pdbg("\nBIOS Lock Enable: %sabled, ",
+ (old & (1 << 1)) ? "en" : "dis");
+ msg_pdbg("BIOS Write Enable: %sabled, ",
+ (old & (1 << 0)) ? "en" : "dis");
+ msg_pdbg("BIOS_CNTL is 0x%x\n", old);
+
+ wanted |= (1 << 0);
+
+ /* Only write the register if it's necessary */
+ if (wanted == old)
+ return 0;
+
+ rmmio_writel(wanted, ilb + 0x1c);
+
+ if ((new = mmio_readl(ilb + 0x1c)) != wanted) {
+ msg_pinfo("WARNING: Setting ILB+0x%x from 0x%x to 0x%x on %s "
+ "failed. New value is 0x%x.\n",
+ 0x1c, old, wanted, name, new);
+ return ERROR_FATAL;
+ }
+ return 0;
+}
+
static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
{
int err;
@@ -535,6 +662,7 @@
static const char *const straps_names_pch8[] = { "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" };
+ static const char *const straps_names_baytrail[] = { "LPC", "unknown", "unknown", "SPI" };
const char *const *straps_names;
switch (ich_generation) {
@@ -570,6 +698,9 @@
case CHIPSET_CENTERTON: // FIXME: Datasheet does not mention GCS at all
straps_names = straps_names_unknown;
break;
+ case CHIPSET_BAYTRAIL:
+ straps_names = straps_names_baytrail;
+ break;
default:
msg_gerr("%s: unknown ICH generation. Please report!\n", __func__);
straps_names = straps_names_unknown;
@@ -619,6 +750,9 @@
/* 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:
+ spibar_offset = 0x0000;
+ break;
case CHIPSET_ICH_UNKNOWN:
return ERROR_FATAL;
case CHIPSET_ICH7:
@@ -712,6 +846,71 @@
return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
}
+/* Baytrail */
+static int enable_flash_baytrail(struct pci_dev *dev, const char *name)
+{
+ int ret, ret_spi;
+ uint8_t bbs, buc;
+ uint32_t tmp, gcs;
+ void *rcrb, *spibar;
+ enum ich_chipset ich_generation = CHIPSET_BAYTRAIL;
+
+ static const char *const straps_names[] = { "LPC", "unknown",
+ "unknown", "SPI" };
+
+ /* Enable Flash Writes */
+ ret = enable_flash_byt(dev, name);
+ if (ret == ERROR_FATAL)
+ return ret;
+
+ /* Get physical address of Root Complex Register Block */
+ tmp = pci_read_long(dev, 0xf0) & 0xffffc000;
+ msg_pdbg("Root Complex Register Block address = 0x%x\n", tmp);
+
+ /* Map RCBA to virtual memory */
+ rcrb = physmap("BYT RCRB", tmp, 0x4000);
+
+ /* Set BBS (Boot BIOS Straps) field of GCS register. */
+ gcs = mmio_readl(rcrb + 0);
+
+ /* Bay Trail BBS (Boot BIOS Straps) field of GCS register.
+ * 00b: LPC
+ * 01b: reserved
+ * 10b: reserved
+ * 11b: SPI
+ */
+
+ msg_pdbg("Setting BBS to SPI\n");
+ gcs = (gcs & ~0xc00) | (0x3 << 10);
+
+ rmmio_writel(gcs, rcrb + 0);
+
+ msg_pdbg("GCS = 0x%x: ", gcs);
+ msg_pdbg("BIOS Interface Lock-Down: %sabled, ",
+ (gcs & 0x1) ? "en" : "dis");
+
+ bbs = (gcs >> 10) & 0x3;
+ msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]);
+
+ buc = mmio_readb(rcrb + 0x3414);
+ msg_pdbg("Top Swap : %s\n",
+ (buc & 1) ? "enabled (A16 inverted)" : "not enabled");
+
+ /* This adds BUS_SPI */
+ tmp = pci_read_long(dev, 0x54) & 0xfffffe00;
+ msg_pdbg("SPI_BASE_ADDRESS = 0x%x\n", tmp);
+ spibar = physmap("BYT SBASE", tmp, 512);
+
+ ret_spi = ich_init_spi(dev, spibar, ich_generation);
+ if (ret_spi == ERROR_FATAL)
+ return ret_spi;
+
+ if (ret || ret_spi)
+ ret = ERROR_NONFATAL;
+
+ return ret;
+}
+
static int via_no_byte_merge(struct pci_dev *dev, const char *name)
{
uint8_t val;
@@ -1476,6 +1675,10 @@
{0x1166, 0x0200, OK, "Broadcom", "OSB4", enable_flash_osb4},
{0x1166, 0x0205, OK, "Broadcom", "HT-1000", enable_flash_ht1000},
{0x17f3, 0x6030, OK, "RDC", "R8610/R3210", enable_flash_rdc_r8610},
+ {0x8086, 0x0f1c, OK, "Intel", "Baytrail", enable_flash_baytrail},
+ {0x8086, 0x0f1d, OK, "Intel", "Baytrail", enable_flash_baytrail},
+ {0x8086, 0x0f1e, OK, "Intel", "Baytrail", enable_flash_baytrail},
+ {0x8086, 0x0f1f, OK, "Intel", "Baytrail", enable_flash_baytrail},
{0x8086, 0x0c60, NT, "Intel", "S12x0", enable_flash_s12x0},
{0x8086, 0x122e, OK, "Intel", "PIIX", enable_flash_piix4},
{0x8086, 0x1234, NT, "Intel", "MPIIX", enable_flash_piix4},
@@ -1511,6 +1714,10 @@
{0x8086, 0x1e5d, NT, "Intel", "HM75", enable_flash_pch7},
{0x8086, 0x1e5e, NT, "Intel", "HM70", enable_flash_pch7},
{0x8086, 0x1e5f, OK, "Intel", "NM70", enable_flash_pch7},
+ {0x8086, 0x1f38, OK, "Intel", "Rangeley/Avoton", enable_flash_baytrail},
+ {0x8086, 0x1f39, OK, "Intel", "Rangeley/Avoton", enable_flash_baytrail},
+ {0x8086, 0x1f3a, OK, "Intel", "Rangeley/Avoton", enable_flash_baytrail},
+ {0x8086, 0x1f3b, OK, "Intel", "Rangeley/Avoton", enable_flash_baytrail},
{0x8086, 0x2310, NT, "Intel", "DH89xxCC", enable_flash_pch7},
{0x8086, 0x2390, NT, "Intel", "Coleto Creek", enable_flash_pch7},
{0x8086, 0x2410, OK, "Intel", "ICH", enable_flash_ich0},
Index: programmer.h
===================================================================
--- programmer.h (revision 1806)
+++ programmer.h (working copy)
@@ -575,6 +575,7 @@
CHIPSET_8_SERIES_LYNX_POINT,
CHIPSET_8_SERIES_LYNX_POINT_LP,
CHIPSET_8_SERIES_WELLSBURG,
+ CHIPSET_BAYTRAIL,
};
/* ichspi.c */
_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom