/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include #include #include #include #include #define FC350_PCIE_INIT_DELAY_US (20 * USECS_PER_MSEC) struct stopwatch pcie_init_timeout_sw; void mb_set_up_early_espi(void) { /* * We don't need to initialize all of the GPIOs that are done * in bootblock_mainboard_early_init(), but we need to release * the EC eSPI reset and do the rest of the configuration. * * This will not be present in the normal boot flow. */ bootblock_mainboard_early_init(); } void bootblock_mainboard_early_init(void) { uint32_t dword; size_t num_gpios, override_num_gpios; const struct soc_amd_gpio *gpios, *override_gpios; /* Beware that the bit definitions for LPC_LDRQ0_PU_EN and LPC_LDRQ0_PD_EN are swapped on Picasso and older compared to Renoir/Cezanne and newer */ dword = pci_read_config32(SOC_LPC_DEV, LPC_MISC_CONTROL_BITS); dword &= ~(LPC_LDRQ0_PU_EN | LPC_LDRQ1_EN | LPC_LDRQ0_EN); dword |= LPC_LDRQ0_PD_EN; pci_write_config32(SOC_LPC_DEV, LPC_MISC_CONTROL_BITS, dword); /* * All LPC decodes need to be cleared before we can configure the LPC pads as secondary * eSPI interface that gets used for the EC communication. This is already done by * lpc_disable_decodes that gets called before this function. */ if (CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK)) return; gpios = variant_espi_gpio_table(&num_gpios); gpio_configure_pads(gpios, num_gpios); gpios = variant_tpm_gpio_table(&num_gpios); gpio_configure_pads(gpios, num_gpios); gpios = variant_early_gpio_table(&num_gpios); override_gpios = variant_early_override_gpio_table(&override_num_gpios); gpio_configure_pads_with_override(gpios, 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); /* Early eSPI interface configuration */ /* Use SPI2 pins for eSPI */ dword = pm_read32(PM_SPI_PAD_PU_PD); dword |= PM_ESPI_CS_USE_DATA2; pm_write32(PM_SPI_PAD_PU_PD, dword); /* Switch the pads that can be used as either LPC or secondary eSPI to 1.8V mode */ dword = pm_read32(PM_ACPI_CONF); dword |= PM_ACPI_S5_LPC_PIN_MODE | PM_ACPI_S5_LPC_PIN_MODE_SEL; pm_write32(PM_ACPI_CONF, dword); } void bootblock_mainboard_init(void) { 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); }