UPSTREAM: mb/google/skyrim: override Markarth PCIe config

Because Markarth PCIe port 1 use for eMMc not SD. So we need override
PCIe config for Markarth. And also the Markarth have NVMe and eMMC
SKU. Follow Winterhold to look at the NVMe CLKREQ signal before
initializing the ports allowing us to identify which device is populated
and only initialize that device.

BRANCH=none
BUG=b:275669215
TEST=emerge-skyrim coreboot chromeos-bootimage

(cherry picked from commit 294a2fd57a79c15aef7934d8fdc704c7b08077aa)

Original-Signed-off-by: John Su <john_su@compal.corp-partner.google.com>
Original-Change-Id: I0b4e4067a30019d742c7589a52badf93b7091615
Original-Reviewed-on: https://review.coreboot.org/c/coreboot/+/74133
Original-Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com>
Original-Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
Original-Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Original-Reviewed-by: Frank Wu <frank_wu@compal.corp-partner.google.com>
GitOrigin-RevId: 294a2fd57a79c15aef7934d8fdc704c7b08077aa
Change-Id: I1bd97a71a29a8fabf1b547934104321da8f255e7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/4406139
Reviewed-by: Rob Barnes <robbarnes@google.com>
Tested-by: CopyBot Service Account <copybot.service@gmail.com>
Commit-Queue: Rob Barnes <robbarnes@google.com>
Tested-by: John Su <john_su@compal.corp-partner.google.com>
diff --git a/src/mainboard/google/skyrim/Kconfig b/src/mainboard/google/skyrim/Kconfig
index f44937b..1eb6926 100644
--- a/src/mainboard/google/skyrim/Kconfig
+++ b/src/mainboard/google/skyrim/Kconfig
@@ -126,6 +126,7 @@
 config USE_VARIANT_DXIO_DESCRIPTOR
 	bool
 	default y if BOARD_GOOGLE_WINTERHOLD
+	default y if BOARD_GOOGLE_MARKARTH
 	default n
 	help
 	  Enable this to allow a variant to override the dxio descriptor values
diff --git a/src/mainboard/google/skyrim/variants/markarth/Makefile.inc b/src/mainboard/google/skyrim/variants/markarth/Makefile.inc
index 83f7700..f9c705a 100644
--- a/src/mainboard/google/skyrim/variants/markarth/Makefile.inc
+++ b/src/mainboard/google/skyrim/variants/markarth/Makefile.inc
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 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/markarth/port_descriptors.c b/src/mainboard/google/skyrim/variants/markarth/port_descriptors.c
new file mode 100644
index 0000000..37edb02
--- /dev/null
+++ b/src/mainboard/google/skyrim/variants/markarth/port_descriptors.c
@@ -0,0 +1,97 @@
+/* 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,
+	},
+};
+
+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,
+	},
+	{
+		/* 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;
+	}
+}