summaryrefslogtreecommitdiff
path: root/src/mainboard/purism/librem_l1um_v2/bootblock.c
diff options
context:
space:
mode:
authorJonathon Hall <jonathon.hall@puri.sm>2023-04-07 15:27:25 -0400
committerFelix Held <felix-coreboot@felixheld.de>2023-09-25 14:10:51 +0000
commitd5f5dd7984a3e3a9938dcb282dfbe199186d1e3e (patch)
tree1a5842d7a193e92f19d424b699fbf54fa1991796 /src/mainboard/purism/librem_l1um_v2/bootblock.c
parentaddf4f882a1a0627dd9753942ba905e7e2592b08 (diff)
mb/purism/librem_l1um_v2: Add support for Purism Librem L1UM v2
This adds support for booting the Librem L1UM v2 mainboard with coreboot, using binaries from the original BIOS. The following features have been tested on PureOS: - USB: front USB3, rear USB3, USB2 header on board - SATA: 8x SATA ports, one M.2 M-key shared with SATA0 - PCIe: two PEG slots, one PCIe slot from PCH, and one M.2 M-key - Network: 2x GbE - Video: BMC VGA and IPMI - Serial: Physical serial port, provided by BMC SuperIO - Hardware monitor - POST code display - TPM2 These binaries are extracted from the original BIOS: - Intel Management Engine - Intel Firmware Descriptor This was developed and tested on a Librem L1UM v2 using a Core i7-9700 CPU. Native graphics init works for the Aspeed AST2500 BMC. For development, the serial port console works from bootblock. Early init waits for the BMC to finish booting since this is required for serial port output. Change-Id: I990f6024d65098a9553d7d1fe7f36614cc55ea19 Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75090 Reviewed-by: Matt DeVillier <matt.devillier@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/mainboard/purism/librem_l1um_v2/bootblock.c')
-rw-r--r--src/mainboard/purism/librem_l1um_v2/bootblock.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/mainboard/purism/librem_l1um_v2/bootblock.c b/src/mainboard/purism/librem_l1um_v2/bootblock.c
new file mode 100644
index 0000000000..d8156695c8
--- /dev/null
+++ b/src/mainboard/purism/librem_l1um_v2/bootblock.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootblock_common.h>
+#include <superio/nuvoton/common/nuvoton.h>
+#include <superio/nuvoton/nct6791d/nct6791d.h>
+#include <superio/aspeed/common/aspeed.h>
+#include <superio/aspeed/ast2400/ast2400.h>
+#include <console/uart.h>
+#include <console/console.h>
+#include <device/pnp_ops.h>
+#include <delay.h>
+#include "gpio.h"
+#include <gpio.h>
+#include <timer.h>
+#include <delay.h>
+
+static int64_t bmc_ready_elapsed = 0;
+
+void bootblock_mainboard_early_init(void)
+{
+ gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table));
+
+ /*
+ * We must wait for the BMC firmware to be ready before proceeding past
+ * early init:
+ * - The BMC UART (the physical serial port) won't work until the BMC is
+ * configured
+ * - The BMC will reset the TPM configuration during startup,
+ * coreboot must not configure or communicate with the TPM before then
+ *
+ * This usually takes about 30 seconds for a boot right after power on.
+ */
+ struct stopwatch sw;
+ stopwatch_init_msecs_expire(&sw, 120 * 1000);
+ while (!stopwatch_expired(&sw)) {
+ /* Wait for J2 to go low - BMC ready signal from BMC firmware */
+ if (!gpio_get(GPP_J2))
+ break;
+ mdelay(1000);
+ }
+ /* Trace the time spent later once the console is up */
+ if (stopwatch_expired(&sw))
+ bmc_ready_elapsed = -1;
+ else
+ bmc_ready_elapsed = stopwatch_duration_msecs(&sw);
+
+ /*
+ * Disable the Nuvoton NCT6791D SuperIO UART1. It is enabled by
+ * default, but the AST2500's is connected to the serial port.
+ */
+ const pnp_devfn_t nvt_serial_dev = PNP_DEV(0x2E, NCT6791D_SP1);
+ nuvoton_pnp_enter_conf_state(nvt_serial_dev);
+ pnp_set_logical_device(nvt_serial_dev);
+ pnp_set_enable(nvt_serial_dev, 0);
+ nuvoton_pnp_exit_conf_state(nvt_serial_dev);
+
+ /* Enable AST2500 SuperIO UART1 */
+ const pnp_devfn_t ast_serial_dev = PNP_DEV(0x4E, AST2400_SUART1);
+ aspeed_enable_serial(ast_serial_dev, CONFIG_TTYS0_BASE);
+}
+
+void bootblock_mainboard_init(void)
+{
+ if (bmc_ready_elapsed >= 0) {
+ printk(BIOS_INFO, "BMC became ready in early init after %lld ms\n",
+ bmc_ready_elapsed);
+ } else {
+ /* Better to boot than to render the system unusable, but some
+ peripherals may not work */
+ printk(BIOS_ERR, "BMC was not ready within timeout, booting anyway\n");
+ }
+}