mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00
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>
This commit is contained in:
parent
c26f27bef8
commit
a8be6dace8
@ -605,6 +605,7 @@ static enum chipbustype enable_flash_ich_report_gcs(
|
||||
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 @@ static enum chipbustype enable_flash_ich_report_gcs(
|
||||
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 @@ static enum chipbustype enable_flash_ich_report_gcs(
|
||||
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 @@ static int enable_flash_pch500(struct pci_dev *const dev, const char *const name
|
||||
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 @@ const struct penable chipset_enables[] = {
|
||||
{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},
|
||||
|
@ -46,6 +46,7 @@ ssize_t ich_number_of_regions(const enum ich_chipset cs, const struct ich_desc_c
|
||||
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 @@ ssize_t ich_number_of_masters(const enum ich_chipset cs, const struct ich_desc_c
|
||||
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 @@ void prettyprint_ich_chipset(enum ich_chipset cs)
|
||||
"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 @@ static const char *pprint_density(enum ich_chipset cs, const struct ich_descript
|
||||
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_density(enum ich_chipset cs, const struct ich_descript
|
||||
|
||||
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 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
|
||||
"reserved",
|
||||
"14 MHz",
|
||||
"reserved"
|
||||
}, {
|
||||
"reserved",
|
||||
"50 MHz",
|
||||
"reserved",
|
||||
"reserved",
|
||||
"33 MHz",
|
||||
"20 MHz",
|
||||
"reserved",
|
||||
"reserved",
|
||||
}};
|
||||
|
||||
switch (cs) {
|
||||
@ -289,6 +301,8 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
|
||||
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 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
|
||||
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 @@ void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct i
|
||||
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 @@ static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_con
|
||||
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 @@ static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const c
|
||||
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 @@ int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors
|
||||
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 @@ static uint32_t read_descriptor_reg(enum ich_chipset cs, uint8_t section, uint16
|
||||
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:
|
||||
|
13
ichspi.c
13
ichspi.c
@ -427,6 +427,7 @@ static void prettyprint_ich9_reg_hsfs(uint16_t reg_val, enum ich_chipset ich_gen
|
||||
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 @@ static void prettyprint_ich9_reg_hsfs(uint16_t reg_val, enum ich_chipset ich_gen
|
||||
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 @@ static void prettyprint_ich9_reg_hsfc(uint16_t reg_val, enum ich_chipset ich_gen
|
||||
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 @@ static void init_chipset_properties(struct swseq_data *swseq, struct hwseq_data
|
||||
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 @@ static void init_chipset_properties(struct swseq_data *swseq, struct hwseq_data
|
||||
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 @@ static int init_ich_default(void *spibar, enum ich_chipset ich_gen)
|
||||
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 @@ static int init_ich_default(void *spibar, enum ich_chipset ich_gen)
|
||||
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 @@ static int init_ich_default(void *spibar, enum ich_chipset ich_gen)
|
||||
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 @@ static int init_ich_default(void *spibar, enum ich_chipset ich_gen)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -352,6 +352,7 @@ enum ich_chipset {
|
||||
CHIPSET_500_SERIES_TIGER_POINT,
|
||||
CHIPSET_APOLLO_LAKE,
|
||||
CHIPSET_GEMINI_LAKE,
|
||||
CHIPSET_ELKHART_LAKE,
|
||||
};
|
||||
|
||||
/* ichspi.c */
|
||||
|
@ -238,6 +238,8 @@ int main(int argc, char *argv[])
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user