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>
diff --git a/ichspi.c b/ichspi.c
index 6601040..e1ede60 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 "