From d2d3993a25c3236d397209f9c2118c3b17ce4f95 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 18 Jan 2019 16:49:37 +0100 Subject: 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 Reviewed-on: https://review.coreboot.org/c/flashrom/+/30995 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- ichspi.c | 112 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 38 deletions(-) (limited to 'ichspi.c') diff --git a/ichspi.c b/ichspi.c index 66010403..e1ede60d 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 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,19 +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; - 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 if (ich_generation == CHIPSET_C620_SERIES_LEWISBURG) { - num_freg = 12; /* 12 MMIO regs, but 16 regions in FD spec */ + 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; @@ -1738,8 +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 { - 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); + } + 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("0xD0: 0x%08x (FPB)\n", tmp); + msg_pdbg("0x%x: 0x%08x (FPB)\n", ICH9_REG_FPB, tmp); + break; } - } - if (desc_valid) { 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 " -- cgit v1.2.3