Nico Huber submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved
Add Elkhart Lake support

Elkhart Lake has a chipset called Mule Creek Canyon which is quite
compatible with 300 series chipsets. There are a few differences though,
e.g. different encoding for the SPI clock values for read and write in
the FLCOMP register. In addition Elkhart Lake has a new PCI device ID
for the SPI controller which is added, too.

TEST=Read and flash complete flash on Siemens MC EHL1

Change-Id: I711e39a3ec9cd7098389231eaa1cb864d615a475
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/60711
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
---
M chipset_enable.c
M ich_descriptors.c
M ichspi.c
M programmer.h
M util/ich_descriptors_tool/ich_descriptors_tool.c
5 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/chipset_enable.c b/chipset_enable.c
index fe7ec15..d9a1d3a 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -605,6 +605,7 @@
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_ELKHART_LAKE:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
reg_name = "BIOS_SPI_BC";
@@ -712,6 +713,7 @@
break;
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
boot_straps = boot_straps_apl;
break;
case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet
@@ -741,6 +743,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
bbs = (gcs >> 6) & 0x1;
break;
default:
@@ -991,6 +994,11 @@
return enable_flash_pch100_or_c620(dev, name, 0x1f, 5, CHIPSET_500_SERIES_TIGER_POINT);
}

+static int enable_flash_mcc(struct pci_dev *const dev, const char *const name)
+{
+ return enable_flash_pch100_or_c620(dev, name, 0x1f, 5, CHIPSET_ELKHART_LAKE);
+}
+
static int enable_flash_apl(struct pci_dev *const dev, const char *const name)
{
return enable_flash_pch100_or_c620(dev, name, 0x0d, 2, CHIPSET_APOLLO_LAKE);
@@ -2105,6 +2113,7 @@
{0x8086, 0x5af0, B_S, DEP, "Intel", "Apollo Lake", enable_flash_apl},
{0x8086, 0x3197, B_S, NT, "Intel", "Gemini Lake", enable_flash_glk},
{0x8086, 0x31e8, B_S, DEP, "Intel", "Gemini Lake", enable_flash_glk},
+ {0x8086, 0x4b24, B_S, DEP, "Intel", "Elkhart Lake", enable_flash_mcc},
{0x8086, 0xa303, B_S, NT, "Intel", "H310", enable_flash_pch300},
{0x8086, 0xa304, B_S, NT, "Intel", "H370", enable_flash_pch300},
{0x8086, 0xa305, B_S, DEP, "Intel", "Z390", enable_flash_pch300},
diff --git a/ich_descriptors.c b/ich_descriptors.c
index 2bff341..d716d1d 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -46,6 +46,7 @@
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_ELKHART_LAKE:
return 16;
case CHIPSET_100_SERIES_SUNRISE_POINT:
return 10;
@@ -72,6 +73,7 @@
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
if (cont->NM <= MAX_NUM_MASTERS)
return cont->NM;
break;
@@ -109,7 +111,7 @@
"8 series Lynx Point", "Baytrail", "8 series Lynx Point LP", "8 series Wellsburg",
"9 series Wildcat Point", "9 series Wildcat Point LP", "100 series Sunrise Point",
"C620 series Lewisburg", "300 series Cannon Point", "400 series Comet Point",
- "500 series Tiger Point", "Apollo Lake", "Gemini Lake",
+ "500 series Tiger Point", "Apollo Lake", "Gemini Lake", "Elkhart Lake",
};
if (cs < CHIPSET_ICH8 || cs - CHIPSET_ICH8 + 1 >= ARRAY_SIZE(chipset_names))
cs = 0;
@@ -205,7 +207,8 @@
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
- case CHIPSET_GEMINI_LAKE: {
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE: {
uint8_t size_enc;
if (idx == 0) {
size_enc = desc->component.dens_new.comp1_density;
@@ -224,7 +227,7 @@

static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
{
- static const char *const freq_str[4][8] = { {
+ static const char *const freq_str[5][8] = { {
"20 MHz",
"33 MHz",
"reserved",
@@ -260,6 +263,15 @@
"reserved",
"14 MHz",
"reserved"
+ }, {
+ "reserved",
+ "50 MHz",
+ "reserved",
+ "reserved",
+ "33 MHz",
+ "20 MHz",
+ "reserved",
+ "reserved",
}};

switch (cs) {
@@ -289,6 +301,8 @@
return freq_str[2][value];
case CHIPSET_500_SERIES_TIGER_POINT:
return freq_str[3][value];
+ case CHIPSET_ELKHART_LAKE:
+ return freq_str[4][value];
case CHIPSET_ICH_UNKNOWN:
default:
return "unknown";
@@ -334,6 +348,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
has_flill1 = true;
break;
default:
@@ -513,7 +528,7 @@
desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
msg_pdbg2("\n");
}
- } else if (cs == CHIPSET_APOLLO_LAKE || cs == CHIPSET_GEMINI_LAKE) {
+ } else if (cs == CHIPSET_APOLLO_LAKE || cs == CHIPSET_GEMINI_LAKE || cs == CHIPSET_ELKHART_LAKE) {
const char *const master_names[] = { "BIOS", "TXE", };
if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
msg_pdbg2("%s: number of masters too high (%d).\n", __func__, desc->content.NM);
@@ -1016,6 +1031,8 @@
return CHIPSET_300_SERIES_CANNON_POINT;
if (content->CSSL == 0x11)
return CHIPSET_500_SERIES_TIGER_POINT;
+ if (content->CSSL == 0x03)
+ return CHIPSET_ELKHART_LAKE;
msg_pwarn("Unknown flash descriptor, assuming 500 series compatibility.\n");
return CHIPSET_500_SERIES_TIGER_POINT;
}
@@ -1038,6 +1055,7 @@
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
/* `freq_read` was repurposed, so can't check on it any more. */
break;
case CHIPSET_100_SERIES_SUNRISE_POINT:
@@ -1194,6 +1212,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
if (idx == 0) {
size_enc = desc->component.dens_new.comp1_density;
} else {
@@ -1232,6 +1251,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
mmio_le_writel(control, spibar + PCH100_REG_FDOC);
return mmio_le_readl(spibar + PCH100_REG_FDOD);
default:
diff --git a/ichspi.c b/ichspi.c
index 329e509..117ff8d 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -427,6 +427,7 @@
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_ELKHART_LAKE:
break;
default:
pprint_reg(HSFS, BERASE, reg_val, ", ");
@@ -439,6 +440,7 @@
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_ELKHART_LAKE:
pprint_reg(HSFS, PRR34_LOCKDN, reg_val, ", ");
pprint_reg(HSFS, WRSDIS, reg_val, ", ");
break;
@@ -460,6 +462,7 @@
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_ELKHART_LAKE:
_pprint_reg(HSFC, PCH100_HSFC_FCYCLE, PCH100_HSFC_FCYCLE_OFF, reg_val, ", ");
pprint_reg(HSFC, WET, reg_val, ", ");
break;
@@ -1780,6 +1783,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
*num_pr = 6; /* Includes GPR0 */
*reg_pr0 = PCH100_REG_FPR0;
swseq->reg_ssfsc = PCH100_REG_SSFSC;
@@ -1815,6 +1819,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
*num_freg = 16;
break;
default:
@@ -1872,6 +1877,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
tmp = mmio_readl(spibar + PCH100_REG_DLOCK);
msg_pdbg("0x0c: 0x%08x (DLOCK)\n", tmp);
prettyprint_pch100_reg_dlock(tmp);
@@ -1949,6 +1955,7 @@
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
case CHIPSET_BAYTRAIL:
+ case CHIPSET_ELKHART_LAKE:
break;
default:
ichspi_bbar = mmio_readl(spibar + ICH9_REG_BBAR);
@@ -1983,6 +1990,7 @@
case CHIPSET_500_SERIES_TIGER_POINT:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
break;
default:
tmp = mmio_readl(spibar + ICH9_REG_FPB);
@@ -2021,8 +2029,9 @@

if (ich_spi_mode == ich_auto &&
(ich_gen == CHIPSET_APOLLO_LAKE ||
- ich_gen == CHIPSET_GEMINI_LAKE)) {
- msg_pdbg("Enabling hardware sequencing by default for Apollo/Gemini Lake.\n");
+ ich_gen == CHIPSET_GEMINI_LAKE ||
+ ich_gen == CHIPSET_ELKHART_LAKE)) {
+ msg_pdbg("Enabling hardware sequencing by default for Apollo/Gemini/Elkhart Lake.\n");
ich_spi_mode = ich_hwseq;
}

diff --git a/programmer.h b/programmer.h
index 647d822..08e5e9c 100644
--- a/programmer.h
+++ b/programmer.h
@@ -352,6 +352,7 @@
CHIPSET_500_SERIES_TIGER_POINT,
CHIPSET_APOLLO_LAKE,
CHIPSET_GEMINI_LAKE,
+ CHIPSET_ELKHART_LAKE,
};

/* ichspi.c */
diff --git a/util/ich_descriptors_tool/ich_descriptors_tool.c b/util/ich_descriptors_tool/ich_descriptors_tool.c
index a1e353b..f743510 100644
--- a/util/ich_descriptors_tool/ich_descriptors_tool.c
+++ b/util/ich_descriptors_tool/ich_descriptors_tool.c
@@ -238,6 +238,8 @@
cs = CHIPSET_APOLLO_LAKE;
else if (strcmp(csn, "gemini") == 0)
cs = CHIPSET_GEMINI_LAKE;
+ else if (strcmp(csn, "elkhart") == 0)
+ cs = CHIPSET_ELKHART_LAKE;
}

ret = read_ich_descriptors_from_dump(buf, len, &cs, &desc);

To view, visit change 60711. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I711e39a3ec9cd7098389231eaa1cb864d615a475
Gerrit-Change-Number: 60711
Gerrit-PatchSet: 5
Gerrit-Owner: Werner Zeh <werner.zeh@siemens.com>
Gerrit-Reviewer: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter@mailbox.org>
Gerrit-MessageType: merged