1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-07-01 22:21:16 +02:00

ichspi: Add Apollo Lake support

It's almost identical to 100 series PCHs and later. There are some
additional FREGs (12..15). To not clutter the `if` conditions further,
make more use of `switch` statements.

Tested on Kontron mAL10. Mark it as DEP as usually the last sector
is not covered by the descriptor layout and can't be read.

Change-Id: I1c464b5b3d151e6d28d5db96495fe874a0a45718
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/30995
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Nico Huber
2019-01-18 16:49:37 +01:00
committed by Nico Huber
parent 3750986348
commit d2d3993a25
4 changed files with 157 additions and 63 deletions

116
ichspi.c
View File

@ -29,6 +29,9 @@
#include "spi.h"
#include "ich_descriptors.h"
/* Apollo Lake */
#define APL_REG_FREG12 0xe0 /* 32 Bytes Flash Region 12 */
/* Sunrise Point */
/* Added HSFS Status bits */
@ -1564,15 +1567,17 @@ static const char *const access_names[] = {
static enum ich_access_protection ich9_handle_frap(uint32_t frap, int i)
{
const int rwperms_unknown = ARRAY_SIZE(access_names);
static const char *const region_names[5] = {
static const char *const region_names[6] = {
"Flash Descriptor", "BIOS", "Management Engine",
"Gigabit Ethernet", "Platform Data"
"Gigabit Ethernet", "Platform Data", "Device Expansion",
};
const char *const region_name = i < ARRAY_SIZE(region_names) ? region_names[i] : "unknown";
uint32_t base, limit;
int rwperms;
int offset = ICH9_REG_FREG0 + i * 4;
const int offset = i < 12
? ICH9_REG_FREG0 + i * 4
: APL_REG_FREG12 + (i - 12) * 4;
uint32_t freg = mmio_readl(ich_spibar + offset);
if (i < 8) {
@ -1716,8 +1721,10 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
memset(&desc, 0x00, sizeof(struct ich_descriptors));
/* Moving registers / bits */
if (ich_generation == CHIPSET_100_SERIES_SUNRISE_POINT) {
num_freg = 10;
switch (ich_generation) {
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
num_pr = 6; /* Includes GPR0 */
reg_pr0 = PCH100_REG_FPR0;
swseq_data.reg_ssfsc = PCH100_REG_SSFSC;
@ -1727,19 +1734,8 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
hwseq_data.addr_mask = PCH100_FADDR_FLA;
hwseq_data.only_4k = true;
hwseq_data.hsfc_fcycle = PCH100_HSFC_FCYCLE;
} else if (ich_generation == CHIPSET_C620_SERIES_LEWISBURG) {
num_freg = 12; /* 12 MMIO regs, but 16 regions in FD spec */
num_pr = 6; /* Includes GPR0 */
reg_pr0 = PCH100_REG_FPR0;
swseq_data.reg_ssfsc = PCH100_REG_SSFSC;
swseq_data.reg_preop = PCH100_REG_PREOP;
swseq_data.reg_optype = PCH100_REG_OPTYPE;
swseq_data.reg_opmenu = PCH100_REG_OPMENU;
hwseq_data.addr_mask = PCH100_FADDR_FLA;
hwseq_data.only_4k = true;
hwseq_data.hsfc_fcycle = PCH100_HSFC_FCYCLE;
} else {
num_freg = 5;
break;
default:
num_pr = 5;
reg_pr0 = ICH9_REG_PR0;
swseq_data.reg_ssfsc = ICH9_REG_SSFS;
@ -1749,6 +1745,21 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
hwseq_data.addr_mask = ICH9_FADDR_FLA;
hwseq_data.only_4k = false;
hwseq_data.hsfc_fcycle = HSFC_FCYCLE;
break;
}
switch (ich_generation) {
case CHIPSET_100_SERIES_SUNRISE_POINT:
num_freg = 10;
break;
case CHIPSET_C620_SERIES_LEWISBURG:
num_freg = 12; /* 12 MMIO regs, but 16 regions in FD spec */
break;
case CHIPSET_APOLLO_LAKE:
num_freg = 16;
break;
default:
num_freg = 5;
break;
}
switch (ich_generation) {
@ -1834,10 +1845,16 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
tmp = mmio_readl(ich_spibar + ICH9_REG_FADDR);
msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp);
if (ich_gen == CHIPSET_100_SERIES_SUNRISE_POINT || ich_gen == CHIPSET_C620_SERIES_LEWISBURG) {
const uint32_t dlock = mmio_readl(ich_spibar + PCH100_REG_DLOCK);
msg_pdbg("0x0c: 0x%08x (DLOCK)\n", dlock);
prettyprint_pch100_reg_dlock(dlock);
switch (ich_gen) {
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
tmp = mmio_readl(ich_spibar + PCH100_REG_DLOCK);
msg_pdbg("0x0c: 0x%08x (DLOCK)\n", tmp);
prettyprint_pch100_reg_dlock(tmp);
break;
default:
break;
}
if (desc_valid) {
@ -1898,37 +1915,51 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
swseq_data.reg_opmenu, mmio_readl(ich_spibar + swseq_data.reg_opmenu));
msg_pdbg("0x%zx: 0x%08x (OPMENU+4)\n",
swseq_data.reg_opmenu + 4, mmio_readl(ich_spibar + swseq_data.reg_opmenu + 4));
if (ich_generation == CHIPSET_ICH8 && desc_valid) {
tmp = mmio_readl(ich_spibar + ICH8_REG_VSCC);
msg_pdbg("0xC1: 0x%08x (VSCC)\n", tmp);
msg_pdbg("VSCC: ");
prettyprint_ich_reg_vscc(tmp, FLASHROM_MSG_DEBUG, true);
} else if (ich_generation != CHIPSET_100_SERIES_SUNRISE_POINT &&
ich_generation != CHIPSET_C620_SERIES_LEWISBURG) {
if (ich_generation != CHIPSET_BAYTRAIL && desc_valid) {
if (desc_valid) {
switch (ich_gen) {
case CHIPSET_ICH8:
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
case CHIPSET_BAYTRAIL:
break;
default:
ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR);
msg_pdbg("0xA0: 0x%08x (BBAR)\n",
ichspi_bbar);
msg_pdbg("0x%x: 0x%08x (BBAR)\n", ICH9_REG_BBAR, ichspi_bbar);
ich_set_bbar(0);
break;
}
if (desc_valid) {
if (ich_gen == CHIPSET_ICH8) {
tmp = mmio_readl(ich_spibar + ICH8_REG_VSCC);
msg_pdbg("0x%x: 0x%08x (VSCC)\n", ICH8_REG_VSCC, tmp);
msg_pdbg("VSCC: ");
prettyprint_ich_reg_vscc(tmp, FLASHROM_MSG_DEBUG, true);
} else {
tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC);
msg_pdbg("0xC4: 0x%08x (LVSCC)\n", tmp);
msg_pdbg("0x%x: 0x%08x (LVSCC)\n", ICH9_REG_LVSCC, tmp);
msg_pdbg("LVSCC: ");
prettyprint_ich_reg_vscc(tmp, FLASHROM_MSG_DEBUG, true);
tmp = mmio_readl(ich_spibar + ICH9_REG_UVSCC);
msg_pdbg("0xC8: 0x%08x (UVSCC)\n", tmp);
msg_pdbg("0x%x: 0x%08x (UVSCC)\n", ICH9_REG_UVSCC, tmp);
msg_pdbg("UVSCC: ");
prettyprint_ich_reg_vscc(tmp, FLASHROM_MSG_DEBUG, false);
tmp = mmio_readl(ich_spibar + ICH9_REG_FPB);
msg_pdbg("0xD0: 0x%08x (FPB)\n", tmp);
}
}
if (desc_valid) {
switch (ich_gen) {
case CHIPSET_ICH8:
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
break;
default:
tmp = mmio_readl(ich_spibar + ICH9_REG_FPB);
msg_pdbg("0x%x: 0x%08x (FPB)\n", ICH9_REG_FPB, tmp);
break;
}
if (read_ich_descriptors_via_fdo(ich_gen, ich_spibar, &desc) == ICH_RET_OK)
prettyprint_ich_descriptors(ich_gen, &desc);
@ -1955,6 +1986,11 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
ich_spi_mode = ich_hwseq;
}
if (ich_spi_mode == ich_auto && ich_gen == CHIPSET_APOLLO_LAKE) {
msg_pdbg("Enabling hardware sequencing by default for Apollo Lake.\n");
ich_spi_mode = ich_hwseq;
}
if (ich_spi_mode == ich_hwseq) {
if (!desc_valid) {
msg_perr("Hardware sequencing was requested "