Martin L Roth has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/73441 )
Change subject: mb/google/skyrim: override winterhold & whiterun pcie config ......................................................................
mb/google/skyrim: override winterhold & whiterun pcie config
Winterhold & Whiterun boards populate either NVMe or eMMC, but not both. This means that there is always one link that is unpopulated. The PCIe configuration code takes longer to verify that a link is unpopulated than to just train the link, so this slows down the boot by roughly 80ms vs the case when the device is present. Not training the device at all lowers boot time by another 20ms, for a total of 100ms saved.
Looking at the NVMe CLKREQ signal before initializing the ports allows us to identify which device is populated and only initialize that device.
BUG=b:271569628 TEST=Boot Whiterun and eMMC or NVMe correctly work, boot time is lower.
Signed-off-by: Martin Roth gaumless@gmail.com Change-Id: I0b87f5e968cd1c87e62a1c0fbdee1fc0723f655d --- M src/mainboard/google/skyrim/variants/whiterun/Makefile.inc A src/mainboard/google/skyrim/variants/whiterun/port_descriptors.c M src/mainboard/google/skyrim/variants/winterhold/Makefile.inc A src/mainboard/google/skyrim/variants/winterhold/port_descriptors.c 4 files changed, 256 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/41/73441/1
diff --git a/src/mainboard/google/skyrim/variants/whiterun/Makefile.inc b/src/mainboard/google/skyrim/variants/whiterun/Makefile.inc index db72b15..26b1ce2 100644 --- a/src/mainboard/google/skyrim/variants/whiterun/Makefile.inc +++ b/src/mainboard/google/skyrim/variants/whiterun/Makefile.inc @@ -2,4 +2,7 @@
subdirs-y += ./memory
+romstage-y += port_descriptors.c + ramstage-y += gpio.c +ramstage-y += port_descriptors.c diff --git a/src/mainboard/google/skyrim/variants/whiterun/port_descriptors.c b/src/mainboard/google/skyrim/variants/whiterun/port_descriptors.c new file mode 100644 index 0000000..9e55a6f --- /dev/null +++ b/src/mainboard/google/skyrim/variants/whiterun/port_descriptors.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <baseboard/variants.h> +#include <console/console.h> +#include <gpio.h> +#include <soc/platform_descriptors.h> +#include <types.h> + +static const fsp_dxio_descriptor emmc_dxio_descriptors[] = { + { + /* WLAN */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 0, + .end_logical_lane = 0, + .device_number = PCI_SLOT(WLAN_DEVFN), + .function_number = PCI_FUNC(WLAN_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .clk_req = CLK_REQ2, + }, + { + /* eMMC */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 1, + .end_logical_lane = 1, + .device_number = PCI_SLOT(SD_DEVFN), + .function_number = PCI_FUNC(SD_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .gpio_group_id = GPIO_27, + .clk_req = CLK_REQ1, + }, + { + /* SSD is disabled */ + .engine_type = UNUSED_ENGINE, + .port_present = false, + .start_logical_lane = 2, + .end_logical_lane = 3, + .turn_off_unused_lanes = true, + }, +}; + +static const fsp_dxio_descriptor nvme_dxio_descriptors[] = { + { + /* WLAN */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 0, + .end_logical_lane = 0, + .device_number = PCI_SLOT(WLAN_DEVFN), + .function_number = PCI_FUNC(WLAN_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .clk_req = CLK_REQ2, + }, + { + /* eMMC is disabled */ + .engine_type = UNUSED_ENGINE, + .port_present = false, + .start_logical_lane = 1, + .end_logical_lane = 1, + .turn_off_unused_lanes = true, + }, + { + /* SSD */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 2, + .end_logical_lane = 3, + .device_number = PCI_SLOT(NVME_DEVFN), + .function_number = PCI_FUNC(NVME_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .gpio_group_id = GPIO_6, + .clk_req = CLK_REQ0, + }, +}; + +#define NVME_CLKREQ_GPIO 92 +void variant_get_dxio_descriptor(const fsp_dxio_descriptor **dxio_descs, size_t *dxio_num) +{ + /* + * We can determine if a device is populated based on the state of the clkreq + * signal. If the device is present, the clkreq is held low by the device. If + * no device is present, clkreq is pulled high by an external pull-up. + * + * This allows checking the state of the NVMe device clkreq signal and enabling + * either eMMC or NVMe based on that. + */ + if (gpio_get(NVME_CLKREQ_GPIO)) { + printk(BIOS_DEBUG, "Enabling eMMC.\n"); + *dxio_num = ARRAY_SIZE(emmc_dxio_descriptors); + *dxio_descs = emmc_dxio_descriptors; + } else { + printk(BIOS_DEBUG, "Enabling NVMe.\n"); + *dxio_num = ARRAY_SIZE(nvme_dxio_descriptors); + *dxio_descs = nvme_dxio_descriptors; + } +} diff --git a/src/mainboard/google/skyrim/variants/winterhold/Makefile.inc b/src/mainboard/google/skyrim/variants/winterhold/Makefile.inc index db72b15..26b1ce2 100644 --- a/src/mainboard/google/skyrim/variants/winterhold/Makefile.inc +++ b/src/mainboard/google/skyrim/variants/winterhold/Makefile.inc @@ -2,4 +2,7 @@
subdirs-y += ./memory
+romstage-y += port_descriptors.c + ramstage-y += gpio.c +ramstage-y += port_descriptors.c diff --git a/src/mainboard/google/skyrim/variants/winterhold/port_descriptors.c b/src/mainboard/google/skyrim/variants/winterhold/port_descriptors.c new file mode 100644 index 0000000..9e55a6f --- /dev/null +++ b/src/mainboard/google/skyrim/variants/winterhold/port_descriptors.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <baseboard/variants.h> +#include <console/console.h> +#include <gpio.h> +#include <soc/platform_descriptors.h> +#include <types.h> + +static const fsp_dxio_descriptor emmc_dxio_descriptors[] = { + { + /* WLAN */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 0, + .end_logical_lane = 0, + .device_number = PCI_SLOT(WLAN_DEVFN), + .function_number = PCI_FUNC(WLAN_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .clk_req = CLK_REQ2, + }, + { + /* eMMC */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 1, + .end_logical_lane = 1, + .device_number = PCI_SLOT(SD_DEVFN), + .function_number = PCI_FUNC(SD_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .gpio_group_id = GPIO_27, + .clk_req = CLK_REQ1, + }, + { + /* SSD is disabled */ + .engine_type = UNUSED_ENGINE, + .port_present = false, + .start_logical_lane = 2, + .end_logical_lane = 3, + .turn_off_unused_lanes = true, + }, +}; + +static const fsp_dxio_descriptor nvme_dxio_descriptors[] = { + { + /* WLAN */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 0, + .end_logical_lane = 0, + .device_number = PCI_SLOT(WLAN_DEVFN), + .function_number = PCI_FUNC(WLAN_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .clk_req = CLK_REQ2, + }, + { + /* eMMC is disabled */ + .engine_type = UNUSED_ENGINE, + .port_present = false, + .start_logical_lane = 1, + .end_logical_lane = 1, + .turn_off_unused_lanes = true, + }, + { + /* SSD */ + .engine_type = PCIE_ENGINE, + .port_present = true, + .start_logical_lane = 2, + .end_logical_lane = 3, + .device_number = PCI_SLOT(NVME_DEVFN), + .function_number = PCI_FUNC(NVME_DEVFN), + .link_speed_capability = GEN3, + .turn_off_unused_lanes = true, + .link_aspm = ASPM_L1, + .link_aspm_L1_1 = true, + .link_aspm_L1_2 = true, + .gpio_group_id = GPIO_6, + .clk_req = CLK_REQ0, + }, +}; + +#define NVME_CLKREQ_GPIO 92 +void variant_get_dxio_descriptor(const fsp_dxio_descriptor **dxio_descs, size_t *dxio_num) +{ + /* + * We can determine if a device is populated based on the state of the clkreq + * signal. If the device is present, the clkreq is held low by the device. If + * no device is present, clkreq is pulled high by an external pull-up. + * + * This allows checking the state of the NVMe device clkreq signal and enabling + * either eMMC or NVMe based on that. + */ + if (gpio_get(NVME_CLKREQ_GPIO)) { + printk(BIOS_DEBUG, "Enabling eMMC.\n"); + *dxio_num = ARRAY_SIZE(emmc_dxio_descriptors); + *dxio_descs = emmc_dxio_descriptors; + } else { + printk(BIOS_DEBUG, "Enabling NVMe.\n"); + *dxio_num = ARRAY_SIZE(nvme_dxio_descriptors); + *dxio_descs = nvme_dxio_descriptors; + } +}