aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Roth <martinroth@chromium.org>2021-05-03 16:21:11 -0600
committerMartin Roth <martinroth@google.com>2021-06-29 18:06:00 +0000
commit324cea9d1b3aa38d115522c67630cad510f6018e (patch)
treedc931cfe7f08a56260910c51a3b89a966b43b10a /src
parent46bee3f48c39960a137b0919e2e8ffb2b0564f99 (diff)
mb/google/guybrush: Update bootblock power-on timings for PCIe
This configures the bootblock portion of the PCIe GPIOs in the correct sequence to meet the power-on timings. Setting the PCIE Reset happens in coreboot instead of in the FSP. The Aux reset lines are anded with the PCIe RST line, so both have to be brought up together. On v1 of guybrush, the PCIe reset line also resets EC communication, so it must be brought up immediately on that version. BUG=b:184796302, b:184598323 TEST=Verify timings between GPIO init sections. All available modules are present after training. Signed-off-by: Martin Roth <martinroth@chromium.org> Change-Id: I2d0b812b654b0cd317a2c8c1ce554e850c96be44 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52868 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/google/guybrush/bootblock.c47
-rw-r--r--src/mainboard/google/guybrush/port_descriptors.c6
-rw-r--r--src/mainboard/google/guybrush/variants/baseboard/gpio.c83
-rw-r--r--src/mainboard/google/guybrush/variants/baseboard/include/baseboard/variants.h11
-rw-r--r--src/mainboard/google/guybrush/variants/guybrush/Makefile.inc1
-rw-r--r--src/mainboard/google/guybrush/variants/guybrush/gpio.c20
6 files changed, 145 insertions, 23 deletions
diff --git a/src/mainboard/google/guybrush/bootblock.c b/src/mainboard/google/guybrush/bootblock.c
index f9f1ab034f..dc5e04657b 100644
--- a/src/mainboard/google/guybrush/bootblock.c
+++ b/src/mainboard/google/guybrush/bootblock.c
@@ -5,8 +5,13 @@
#include <bootblock_common.h>
#include <baseboard/variants.h>
#include <console/console.h>
+#include <delay.h>
#include <device/pci_ops.h>
#include <soc/pci_devs.h>
+#include <timer.h>
+
+#define FC350_PCIE_INIT_DELAY_US (20 * USECS_PER_MSEC)
+struct stopwatch pcie_init_timeout_sw;
void mb_set_up_early_espi(void)
{
@@ -22,13 +27,21 @@ void mb_set_up_early_espi(void)
void bootblock_mainboard_early_init(void)
{
- size_t num_gpios;
uint32_t dword;
- const struct soc_amd_gpio *gpios;
+ size_t base_num_gpios, override_num_gpios;
+ const struct soc_amd_gpio *base_gpios, *override_gpios;
if (!CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK)) {
- gpios = variant_early_gpio_table(&num_gpios);
- program_gpios(gpios, num_gpios);
+ base_gpios = variant_early_gpio_table(&base_num_gpios);
+ override_gpios = variant_early_override_gpio_table(&override_num_gpios);
+
+ gpio_configure_pads_with_override(base_gpios, base_num_gpios,
+ override_gpios, override_num_gpios);
+
+ /* Set a timer to make sure there's enough delay for
+ * the Fibocom 350 PCIe init
+ */
+ stopwatch_init_usecs_expire(&pcie_init_timeout_sw, FC350_PCIE_INIT_DELAY_US);
}
printk(BIOS_DEBUG, "Bootblock configure eSPI\n");
@@ -51,7 +64,31 @@ void bootblock_mainboard_early_init(void)
void bootblock_mainboard_init(void)
{
- /* Put FPMCU check after EC initialization */
+ size_t base_num_gpios, override_num_gpios;
+ const struct soc_amd_gpio *base_gpios, *override_gpios;
+ int i = 0;
+
+ /* Make sure that at least 20ms has elapsed since enabling WWAN power
+ * in bootblock_mainboard_early_init.
+ * This is only applicable if verstage is not in the PSP and the board
+ * is using the fibocom 350 WLAN card, so this typically will not be hit.
+ */
+ if (!CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && variant_has_pcie_wwan()) {
+ while (!stopwatch_expired(&pcie_init_timeout_sw)) {
+ mdelay(1);
+ i++;
+ };
+ if (i)
+ printk(BIOS_DEBUG, "Delayed %d ms for PCIe\n", i);
+ }
+
+ base_gpios = variant_bootblock_gpio_table(&base_num_gpios);
+ override_gpios = variant_bootblock_override_gpio_table(&override_num_gpios);
+
+ gpio_configure_pads_with_override(base_gpios, base_num_gpios, override_gpios,
+ override_num_gpios);
+
+ /* FPMCU check needs to happen after EC initialization for FW_CONFIG bits */
if (variant_has_fpmcu())
variant_fpmcu_reset();
}
diff --git a/src/mainboard/google/guybrush/port_descriptors.c b/src/mainboard/google/guybrush/port_descriptors.c
index 489bccdec0..a83db6cd1f 100644
--- a/src/mainboard/google/guybrush/port_descriptors.c
+++ b/src/mainboard/google/guybrush/port_descriptors.c
@@ -6,7 +6,7 @@
#include <soc/gpio.h>
#include <types.h>
-/* TODO: test if this really works */
+/* All PCIe Resets are handled in coreboot */
static const fsp_dxio_descriptor guybrush_czn_dxio_descriptors[] = {
{ /* WLAN */
.engine_type = PCIE_ENGINE,
@@ -18,7 +18,6 @@ static const fsp_dxio_descriptor guybrush_czn_dxio_descriptors[] = {
.link_aspm = ASPM_L1,
.turn_off_unused_lanes = true,
.clk_req = CLK_REQ0,
- .gpio_group_id = GPIO_29,
.port_params = {PP_PSPP_AC, 0x133, PP_PSPP_DC, 0x122}
},
{ /* SD */
@@ -31,7 +30,6 @@ static const fsp_dxio_descriptor guybrush_czn_dxio_descriptors[] = {
.link_aspm = ASPM_L1,
.turn_off_unused_lanes = true,
.clk_req = CLK_REQ1,
- .gpio_group_id = GPIO_70,
.port_params = {PP_PSPP_AC, 0x133, PP_PSPP_DC, 0x122}
},
{ /* WWAN */
@@ -44,7 +42,6 @@ static const fsp_dxio_descriptor guybrush_czn_dxio_descriptors[] = {
.link_aspm = ASPM_L1,
.turn_off_unused_lanes = true,
.clk_req = CLK_REQ2,
- .gpio_group_id = GPIO_18,
.port_params = {PP_PSPP_AC, 0x133, PP_PSPP_DC, 0x122}
},
{ /* NVME */
@@ -57,7 +54,6 @@ static const fsp_dxio_descriptor guybrush_czn_dxio_descriptors[] = {
.link_aspm = ASPM_L1,
.turn_off_unused_lanes = true,
.clk_req = CLK_REQ3,
- .gpio_group_id = GPIO_40,
.port_params = {PP_PSPP_AC, 0x133, PP_PSPP_DC, 0x122}
},
{ /* TODO: remove this temporay workaround */
diff --git a/src/mainboard/google/guybrush/variants/baseboard/gpio.c b/src/mainboard/google/guybrush/variants/baseboard/gpio.c
index eb42ab505f..dc72cdb5c6 100644
--- a/src/mainboard/google/guybrush/variants/baseboard/gpio.c
+++ b/src/mainboard/google/guybrush/variants/baseboard/gpio.c
@@ -7,6 +7,7 @@
#include <soc/gpio.h>
/* GPIO configuration in ramstage*/
+/* Please make sure that *ALL* GPIOs are configured in this table */
static const struct soc_amd_gpio base_gpio_table[] = {
/* PWR_BTN_L */
PAD_NF(GPIO_0, PWR_BTN_L, PULL_NONE),
@@ -40,7 +41,7 @@ static const struct soc_amd_gpio base_gpio_table[] = {
/* SOC_SAR_INT_L */
PAD_SCI(GPIO_17, PULL_NONE, EDGE_LOW),
/* WWAN_AUX_RESET_L */
- PAD_GPO(GPIO_18, LOW),
+ PAD_GPO(GPIO_18, HIGH),
/* I2C3_SCL */
PAD_NF(GPIO_19, I2C3_SCL, PULL_NONE),
/* I2C3_SDA */
@@ -55,12 +56,11 @@ static const struct soc_amd_gpio base_gpio_table[] = {
PAD_GPO(GPIO_24, HIGH),
/* GPIO_25: Not available */
/* PCIE_RST0_L */
- /* TODO: change back to PCIE_RST_L when we figure out why PCIE_RST doesn't go high. */
- PAD_GPO(GPIO_26, HIGH),
+ PAD_NFO(GPIO_26, PCIE_RST_L, HIGH),
/* PCIE_RST1_L */
PAD_NF(GPIO_27, PCIE_RST1_L, PULL_NONE),
/* GPIO_28: Not available */
- /* WLAN_AUX_RESET */
+ /* WLAN_AUX_RESET (Active HIGH)*/
PAD_GPO(GPIO_29, LOW),
/* ESPI_CS_L */
PAD_NF(GPIO_30, ESPI_CS_L, PULL_NONE),
@@ -167,22 +167,32 @@ static const struct soc_amd_gpio base_gpio_table[] = {
/* Early GPIO configuration */
static const struct soc_amd_gpio early_gpio_table[] = {
+ /* WWAN_AUX_RESET_L */
+ PAD_GPO(GPIO_18, LOW),
+ /* WLAN_AUX_RESET (ACTIVE HIGH) */
+ PAD_GPO(GPIO_29, HIGH),
+ /* SSD_AUX_RESET_L */
+ PAD_GPO(GPIO_40, LOW),
+ /* SD_AUX_RESET_L */
+ PAD_GPO(GPIO_69, LOW),
+ /* Guybrush BID>1: Unused TP27; BID==1: SD_AUX_RESET_L */
+ PAD_NC(GPIO_70),
+ /* PCIE_RST0_L */
+ PAD_NFO(GPIO_26, PCIE_RST_L, HIGH),
+
+/* Power on WLAN & WWAN */
/* EN_PP3300_WLAN */
PAD_GPO(GPIO_6, HIGH),
/* EN_PWR_WWAN_X */
PAD_GPO(GPIO_8, HIGH),
- /* WWAN_DISABLE */
- PAD_GPO(GPIO_85, LOW),
- /* WLAN_DISABLE */
- PAD_GPO(GPIO_130, LOW),
+
+/* Enable ESPI, GSC Interrupt & I2C Communication */
/* GSC_SOC_INT_L */
PAD_INT(GPIO_3, PULL_NONE, EDGE_LOW, STATUS_DELIVERY),
/* I2C3_SCL */
PAD_NF(GPIO_19, I2C3_SCL, PULL_NONE),
/* I2C3_SDA */
PAD_NF(GPIO_20, I2C3_SDA, PULL_NONE),
- /* PCIE_RST0_L */
- PAD_GPO(GPIO_26, HIGH),
/* ESPI_CS_L */
PAD_NF(GPIO_30, ESPI_CS_L, PULL_NONE),
/* ESPI_SOC_CLK */
@@ -197,17 +207,58 @@ static const struct soc_amd_gpio early_gpio_table[] = {
PAD_NF(GPIO_107, SPI2_HOLD_L_ESPI2_D3, PULL_NONE),
/* ESPI_ALERT_L */
PAD_NF(GPIO_108, ESPI_ALERT_D1, PULL_NONE),
+
+/* Enable UART 0 */
/* UART0_RXD */
PAD_NF(GPIO_141, UART0_RXD, PULL_NONE),
/* UART0_TXD */
PAD_NF(GPIO_143, UART0_TXD, PULL_NONE),
};
+/* Power-on timing requirements:
+ * Fibocom 350-GL:
+ * FCP0# goes high (GPIO 6) to Reset# high (GPIO 24): 20ms min
+ * FCP0# goes high (GPIO 6) to PERST# high (GPIO 26): 100ms min
+ * PERST# high (GPIO 26) to PCIE Training (FSP-M): 23ms min
+ *
+ * Realtek RTL8852AE:
+ * Power (3.3 V) valid to PERST# high (GPIO_26): 50ms min
+ *
+ * Qualcomm WCN6856:
+ * Power (3.3 V) valid to PERST# high (GPIO_26): 50ms min
+ *
+ * RTS5250S / RTS5227S / RTS5261S
+ * Power (3.3 V) valid to PERST# high (GPIO_69/70): 1ms min
+ *
+ * PCIe spec:
+ * Power (3.3 V) valid to PERST# high (GPIO_26): 50ms min (SUGGESTED)
+ *
+ * NVME adapters planned for Guybrush:
+ * No power on timings specified - Assumed to require PCIe Spec suggested
+ * guidelines. Testing seems to bear out this assumption.
+ */
+
+static const struct soc_amd_gpio bootblock_gpio_table[] = {
+/* Enable WWAN & WLAN */
+ /* WWAN_RST_L */
+ PAD_GPO(GPIO_24, HIGH),
+ /* WWAN_DISABLE */
+ PAD_GPO(GPIO_85, LOW),
+ /* WLAN_DISABLE */
+ PAD_GPO(GPIO_130, LOW),
+};
+
/* GPIO configuration for sleep */
static const struct soc_amd_gpio sleep_gpio_table[] = {
/* TODO: Fill sleep gpio configuration */
};
+const struct soc_amd_gpio *__weak variant_bootblock_gpio_table(size_t *size)
+{
+ *size = ARRAY_SIZE(bootblock_gpio_table);
+ return bootblock_gpio_table;
+}
+
const struct soc_amd_gpio *__weak variant_base_gpio_table(size_t *size)
{
*size = ARRAY_SIZE(base_gpio_table);
@@ -219,6 +270,18 @@ const struct soc_amd_gpio *__weak variant_override_gpio_table(size_t *size)
return NULL;
}
+const struct soc_amd_gpio * __weak variant_early_override_gpio_table(size_t *size)
+{
+ *size = 0;
+ return NULL;
+}
+
+const struct soc_amd_gpio * __weak variant_bootblock_override_gpio_table(size_t *size)
+{
+ *size = 0;
+ return NULL;
+}
+
const struct soc_amd_gpio *__weak variant_early_gpio_table(size_t *size)
{
*size = ARRAY_SIZE(early_gpio_table);
diff --git a/src/mainboard/google/guybrush/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/guybrush/variants/baseboard/include/baseboard/variants.h
index 6b82d183d7..f1bbfd3b46 100644
--- a/src/mainboard/google/guybrush/variants/baseboard/include/baseboard/variants.h
+++ b/src/mainboard/google/guybrush/variants/baseboard/include/baseboard/variants.h
@@ -19,14 +19,19 @@
*/
const struct soc_amd_gpio *variant_base_gpio_table(size_t *size);
/*
- * This function allows variant to override any GPIOs that are different than the base GPIO
- * configuration provided by variant_base_gpio_table().
+ * These functions allow variants to override any GPIOs that are different than the base GPIO
+ * configuration provided without having to replace the entire file.
*/
const struct soc_amd_gpio *variant_override_gpio_table(size_t *size);
+const struct soc_amd_gpio *variant_early_override_gpio_table(size_t *size);
+const struct soc_amd_gpio *variant_bootblock_override_gpio_table(size_t *size);
-/* This function provides early GPIO init in bootblock or psp. */
+/* This function provides early GPIO init in early bootblock or psp. */
const struct soc_amd_gpio *variant_early_gpio_table(size_t *size);
+/* This function provides GPIO settings at the end of bootblock. */
+const struct soc_amd_gpio *variant_bootblock_gpio_table(size_t *size);
+
/* This function provides GPIO settings before entering sleep. */
const struct soc_amd_gpio *variant_sleep_gpio_table(size_t *size);
diff --git a/src/mainboard/google/guybrush/variants/guybrush/Makefile.inc b/src/mainboard/google/guybrush/variants/guybrush/Makefile.inc
index ba8514c4c2..8255ba8ebf 100644
--- a/src/mainboard/google/guybrush/variants/guybrush/Makefile.inc
+++ b/src/mainboard/google/guybrush/variants/guybrush/Makefile.inc
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+bootblock-y += gpio.c
ramstage-y += gpio.c
subdirs-y += ./memory
diff --git a/src/mainboard/google/guybrush/variants/guybrush/gpio.c b/src/mainboard/google/guybrush/variants/guybrush/gpio.c
index 05c1542124..e71ed9d57a 100644
--- a/src/mainboard/google/guybrush/variants/guybrush/gpio.c
+++ b/src/mainboard/google/guybrush/variants/guybrush/gpio.c
@@ -18,6 +18,13 @@ static const struct soc_amd_gpio bid1_gpio_table[] = {
PAD_GPI(GPIO_74, PULL_NONE),
};
+/* This table is used by guybrush variant with board version < 2. */
+/* Use AUX Reset lines instead of PCIE_RST for Board Version 1 */
+static const struct soc_amd_gpio bid1_early_gpio_table[] = {
+ /* SD_AUX_RESET_L */
+ PAD_GPO(GPIO_70, HIGH),
+};
+
const struct soc_amd_gpio *variant_override_gpio_table(size_t *size)
{
uint32_t board_version = board_id();
@@ -30,3 +37,16 @@ const struct soc_amd_gpio *variant_override_gpio_table(size_t *size)
return NULL;
}
+
+const struct soc_amd_gpio *variant_early_override_gpio_table(size_t *size)
+{
+ uint32_t board_version = board_id();
+ *size = 0;
+
+ if (board_version < 2) {
+ *size = ARRAY_SIZE(bid1_early_gpio_table);
+ return bid1_early_gpio_table;
+ }
+
+ return NULL;
+}