diff --git a/configs/config.msi_ms7e56 b/configs/config.msi_ms7e56 index cfa7d3b5192..d140b50d029 100644 --- a/configs/config.msi_ms7e56 +++ b/configs/config.msi_ms7e56 @@ -1,30 +1,37 @@ +CONFIG_LOCALVERSION="v0.9.0-rc1" +CONFIG_OPTION_BACKEND_NONE=y CONFIG_VENDOR_MSI=y +CONFIG_MAINBOARD_VERSION="1.0" CONFIG_ONBOARD_VGA_IS_PRIMARY=y CONFIG_VGA_BIOS=y -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_L1_SUB_STATE=y -CONFIG_PCIEXP_CLK_PM=y +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x2000000 CONFIG_EDK2_BOOT_TIMEOUT=3 CONFIG_PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS=39 CONFIG_VGA_BIOS_FILE="Phoenix_generic_vbios.bin" CONFIG_EDK2_BOOT_MANAGER_ESCAPE=y CONFIG_EDK2_FOLLOW_BGRT_SPEC=y CONFIG_BOARD_MSI_PRO_B850_P=y +CONFIG_TPM_MEASURED_BOOT=y CONFIG_EDK2_BOOTSPLASH_FILE="3rdparty/dasharo-blobs/dasharo/bootsplash.bmp" CONFIG_PCIEXP_COMMON_CLOCK=y CONFIG_ALWAYS_ALLOW_ABOVE_4G_ALLOCATION=y CONFIG_SOC_AMD_COMMON_BLOCK_APOB_NV_DISABLE=y -# CONFIG_ON_DEVICE_ROM_LOAD is not set -CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES=y -CONFIG_YABEL_DIRECTHW=y +CONFIG_NO_GFX_INIT=y CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS=y -CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y +CONFIG_DRIVERS_EFI_VARIABLE_STORE=y +CONFIG_DRIVERS_EFI_FW_INFO=y +CONFIG_DRIVERS_EFI_MAIN_FW_VERSION=0x00090001 +CONFIG_DRIVERS_EFI_MAIN_FW_LSV=0x00090001 +CONFIG_DRIVERS_EFI_UPDATE_CAPSULES=y +CONFIG_TPM2=y +# CONFIG_TPM_HASH_SHA1 is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0=y CONFIG_PAYLOAD_EDK2=y -CONFIG_EDK2_TAG_OR_REV="origin/cbmem_pci_rb_info" -CONFIG_EDK2_DEBUG=y +CONFIG_EDK2_TAG_OR_REV="origin/dasharo" +CONFIG_EDK2_CBMEM_LOGGING=y CONFIG_EDK2_LOAD_OPTION_ROMS=y # CONFIG_EDK2_PS2_SUPPORT is not set -CONFIG_EDK2_CUSTOM_BUILD_PARAMS="--pcd gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask=0x07" +CONFIG_EDK2_SERIAL_SUPPORT=y CONFIG_EDK2_ENABLE_IPXE=y CONFIG_IPXE_ADD_SCRIPT=y CONFIG_IPXE_SCRIPT="3rdparty/dasharo-blobs/dasharo/dasharo.ipxe" @@ -42,17 +49,18 @@ CONFIG_EDK2_DASHARO_NETWORK_CONFIG=y CONFIG_EDK2_DASHARO_CHIPSET_CONFIG=y CONFIG_EDK2_DASHARO_POWER_CONFIG=y CONFIG_EDK2_DASHARO_PCI_CONFIG=y -CONFIG_EDK2_DASHARO_NETWORK_BOOT_DEFAULT_ENABLE=y CONFIG_EDK2_DASHARO_SERIAL_REDIRECTION_DEFAULT_ENABLE=y CONFIG_EDK2_BOOT_MENU_KEY=0x0015 CONFIG_EDK2_SETUP_MENU_KEY=0x0008 CONFIG_EDK2_CREATE_PREINSTALLED_BOOT_OPTIONS=y +CONFIG_EDK2_USE_UEFIVAR_BACKED_TPM_PPI=y CONFIG_EDK2_ENABLE_FAST_BOOT_FEATURE=y CONFIG_EDK2_ENABLE_QUIET_BOOT_FEATURE=y # CONFIG_EDK2_GRAPHICAL_CAPSULE_PROGRESS is not set # CONFIG_EDK2_FUM_AUTO_IPXE_BOOT is not set +CONFIG_EDK2_CAPSULE_DOES_NOT_SURVIVE_RESET=y +CONFIG_EDK2_SHOW_CAPSULE_REPORT=y CONFIG_DISPLAY_MTRRS=y CONFIG_OPENSIL_DEBUG_PREFIX=y CONFIG_OPENSIL_DEBUG_APOB=y -# CONFIG_OPENSIL_DEBUG_FCH is not set # CONFIG_OPENSIL_DEBUG_XUSL_CMN is not set diff --git a/payloads/external/Makefile.mk b/payloads/external/Makefile.mk index d770ddc3ca4..3b8770833de 100644 --- a/payloads/external/Makefile.mk +++ b/payloads/external/Makefile.mk @@ -305,8 +305,11 @@ $(obj)/UEFIPAYLOAD.fd: $(DOTCONFIG) $(IPXE_EFI) CONFIG_EDK2_FW_VERSION=L"$(CONFIG_LOCALVERSION)" \ CONFIG_EDK2_FW_VENDOR=L"$(CONFIG_BIOS_VENDOR)" \ CONFIG_EDK2_FW_RELEASE_DATE=L"$(call get_build_value,COREBOOT_DMI_DATE)" \ - CONFIG_EDK2_FW_REVISION=$(shell printf 0x"%04x%04x" $(DASHARO_MAJOR_VERSION) $(DASHARO_MINOR_VERSION)) - + CONFIG_EDK2_FW_REVISION=$(shell printf 0x"%04x%04x" $(DASHARO_MAJOR_VERSION) $(DASHARO_MINOR_VERSION)) \ + CONFIG_EDK2_AMD_GOP_DRIVER=$(CONFIG_EDK2_AMD_GOP_DRIVER) \ + CONFIG_EDK2_VGA_BIOS_VENDOR_ID=0x$(word 1,$(subst $(comma),$(spc),$(call strip_quotes,$(CONFIG_VGA_BIOS_ID)))) \ + CONFIG_EDK2_VGA_BIOS_DEVICE_ID=0x$(word 2,$(subst $(comma),$(spc),$(call strip_quotes,$(CONFIG_VGA_BIOS_ID)))) \ + CONFIG_VGA_BIOS_FILE=$(CONFIG_VGA_BIOS_FILE) $(obj)/ShimmedUniversalPayload.elf: $(DOTCONFIG) $(MAKE) -C payloads/external/edk2 UniversalPayload \ diff --git a/payloads/external/edk2/Kconfig b/payloads/external/edk2/Kconfig index 870e2ad66e1..e3c4c654371 100644 --- a/payloads/external/edk2/Kconfig +++ b/payloads/external/edk2/Kconfig @@ -291,9 +291,17 @@ config EDK2_GOP_DRIVER help Select this option to have edk2 use an external GOP driver for display init. +config EDK2_AMD_GOP_DRIVER + bool "Add an AMD GOP driver to the Tianocore build" + depends on VGA_BIOS && NO_GFX_INIT && !EDK2_REPO_OFFICIAL && !EDK2_DISABLE_OPTION_ROMS + default y if VGA_BIOS && NO_GFX_INIT && EDK2_REPO_MRCHROMEBOX + help + Select this option to have edk2 use an external GOP driver for AMD display init. + config EDK2_GOP_FILE string "GOP driver file" - depends on EDK2_GOP_DRIVER + depends on EDK2_GOP_DRIVER || EDK2_AMD_GOP_DRIVER + default "AmdGopDriver.efi" if EDK2_AMD_GOP_DRIVER default "IntelGopDriver.efi" help The name of the GOP driver file passed to edk2. diff --git a/payloads/external/edk2/Makefile b/payloads/external/edk2/Makefile index 64fe3eb9e5d..2c1af8f801a 100644 --- a/payloads/external/edk2/Makefile +++ b/payloads/external/edk2/Makefile @@ -462,6 +462,12 @@ endif ifneq ($(CONFIG_EDK2_FUM_AUTO_IPXE_BOOT),y) BUILD_STR += --pcd gDasharoSystemFeaturesTokenSpaceGuid.PcdFumAutoIpxeBoot=FALSE endif +# USE_AMD_PLATFORM_GOP = FALSE +ifeq ($(CONFIG_EDK2_AMD_GOP_DRIVER),y) +BUILD_STR += -D USE_AMD_PLATFORM_GOP=TRUE +BUILD_STR += --pcd gDasharoPayloadPkgTokenSpaceGuid.AmdVbiosOptionRomVendorId=$(CONFIG_EDK2_VGA_BIOS_VENDOR_ID) +BUILD_STR += --pcd gDasharoPayloadPkgTokenSpaceGuid.AmdVbiosOptionRomDeviceId=$(CONFIG_EDK2_VGA_BIOS_DEVICE_ID) +endif BUILD_STR += --pcd gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString=$(CONFIG_EDK2_FW_VERSION) BUILD_STR += --pcd gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor=$(CONFIG_EDK2_FW_VENDOR) @@ -560,6 +566,11 @@ gop_driver: $(EDK2_PATH) cp $(top)/$(CONFIG_EDK2_GOP_FILE) $(EDK2_PATH)/$(PAYLOAD_NAME)/IntelGopDriver.efi; \ cp $(top)/$(CONFIG_INTEL_GMA_VBT_FILE) $(EDK2_PATH)/$(PAYLOAD_NAME)/vbt.bin; \ fi; \ + if [ -n "$(CONFIG_EDK2_AMD_GOP_DRIVER)" ]; then \ + echo "Using GOP driver $(CONFIG_EDK2_GOP_FILE)"; \ + cp $(top)/$(CONFIG_EDK2_GOP_FILE) $(EDK2_PATH)/$(PAYLOAD_NAME)/AmdGopDriver.efi; \ + cp $(top)/$(CONFIG_VGA_BIOS_FILE) $(EDK2_PATH)/$(PAYLOAD_NAME)/Vbios.bin; \ + fi; \ lan_rom: $(EDK2_PATH) case "$(CONFIG_EDK2_LAN_ROM_DRIVER)" in \ diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index 11f82732395..2f98f659068 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -704,8 +704,10 @@ void acpi_create_vfct(const struct device *device, current = acpi_fill_vfct_func(device, vfct, current); /* If no BIOS image, return with header->length == 0. */ - if (!vfct->VBIOSImageOffset) + if (!vfct->VBIOSImageOffset) { + header->length = 0; return; + } /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)vfct; diff --git a/src/acpi/acpigen_pci_root_resource_producer.c b/src/acpi/acpigen_pci_root_resource_producer.c index b49c653109d..75a206e5441 100644 --- a/src/acpi/acpigen_pci_root_resource_producer.c +++ b/src/acpi/acpigen_pci_root_resource_producer.c @@ -122,7 +122,8 @@ void pci_domain_fill_ssdt(const struct device *domain) if (domain->downstream->bridge_ctrl & PCI_BRIDGE_CTL_VGA) { printk(BIOS_DEBUG, "%s _CRS: adding VGA resource\n", acpi_device_name(domain)); acpigen_resource_producer_io(VGA_IO_BASE, VGA_IO_LIMIT); - acpigen_resource_producer_mmio(VGA_MMIO_BASE, VGA_MMIO_LIMIT, + /* Report VGA MMIO + extra 128K for VGA OptionROM in legacy C segment */ + acpigen_resource_producer_mmio(VGA_MMIO_BASE, VGA_MMIO_LIMIT + 0x20000, MEM_RSRC_FLAG_MEM_READ_WRITE | MEM_RSRC_FLAG_MEM_ATTR_CACHE); } diff --git a/src/drivers/amd/promontory21/Kconfig b/src/drivers/amd/promontory21/Kconfig new file mode 100644 index 00000000000..6dfc58f0cdb --- /dev/null +++ b/src/drivers/amd/promontory21/Kconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config DRIVERS_AMD_PROMONTORY21 + bool + help + Enable AMD Promontory21 chip driver. diff --git a/src/drivers/amd/promontory21/Makefile.mk b/src/drivers/amd/promontory21/Makefile.mk new file mode 100644 index 00000000000..ca1f7fb08df --- /dev/null +++ b/src/drivers/amd/promontory21/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_DRIVERS_AMD_PROMONTORY21) += chip.c diff --git a/src/drivers/amd/promontory21/acpi/prom21_gpio.asl b/src/drivers/amd/promontory21/acpi/prom21_gpio.asl new file mode 100644 index 00000000000..4f126ff2947 --- /dev/null +++ b/src/drivers/amd/promontory21/acpi/prom21_gpio.asl @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +Scope (\_SB) +{ + Name (TGPI, 0x0F) + Device (PTIO) + { + Name (_HID, "AMDIF031") + Name (_CID, "AMDIF031") + Name (_UID, 0) + Method (_CRS, 0, NotSerialized) + { + Name (RBUF, ResourceTemplate () + { + Memory32Fixed (ReadWrite, + 0xFEC40000, + 0x00001000, + ) + }) + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + } + + Device (ASMT) + { + Name (_HID, "ASMT0001") + Name (_CID, "ASMT0001") + Name (_UID, 0) + Method (_CRS, 0, NotSerialized) + { + Name (RBUF, ResourceTemplate () + { + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0000 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0001 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0002 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0003 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0004 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0005 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0006 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0007 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0008 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0009 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000A + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000B + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000C + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000D + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000E + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x000F + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0010 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0011 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0012 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0013 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0014 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0015 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0016 + } + GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone, + "\\_SB.PTIO", 0x00, ResourceConsumer, , + RawDataBuffer (0x01) { 0x01 }) + { + 0x0017 + } + }) + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + If ((TGPI == One)) + { + Return (0x0F) + } + Else + { + Return (Zero) + } + } + } +} diff --git a/src/drivers/amd/promontory21/chip.c b/src/drivers/amd/promontory21/chip.c new file mode 100644 index 00000000000..e73b294ac45 --- /dev/null +++ b/src/drivers/amd/promontory21/chip.c @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +#include "chip.h" + +static const char *prom21_sata_acpi_name(const struct device *dev) +{ + return "STCR"; +} + +static const char *prom21_usp_acpi_name(const struct device *dev) +{ + return "UP00"; +} + +static const char *prom21_dsp_acpi_name(const struct device *dev) +{ + char *name; + + if (dev->path.type != DEVICE_PATH_PCI) + return NULL; + + name = malloc(ACPI_NAME_BUFFER_SIZE); + snprintf(name, ACPI_NAME_BUFFER_SIZE, "DP%02X", dev->path.pci.devfn); + name[4] = '\0'; + + return name; +} + +struct device_operations prom21_sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .ops_pci = &pci_dev_ops_pci, + .acpi_name = prom21_sata_acpi_name, + .acpi_fill_ssdt = acpi_device_write_pci_dev, +}; + +static struct pci_operations prom21_pcie_ops = { + .set_subsystem = pci_dev_set_subsystem, +}; + +struct device_operations amd_prom21_usp_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .acpi_name = prom21_usp_acpi_name, + .acpi_fill_ssdt = acpi_device_write_pci_dev, + .ops_pci = &prom21_pcie_ops, +}; + +struct device_operations amd_prom21_dsp_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .acpi_name = prom21_dsp_acpi_name, + .acpi_fill_ssdt = acpi_device_write_pci_dev, + .ops_pci = &prom21_pcie_ops, +}; + +struct chip_operations drivers_amd_promontory21_ops = { + .name = "AMD Promontory21", +}; diff --git a/src/drivers/amd/promontory21/chip.h b/src/drivers/amd/promontory21/chip.h new file mode 100644 index 00000000000..7ed45bfe77c --- /dev/null +++ b/src/drivers/amd/promontory21/chip.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef PROMONTORY21_CHIP_H +#define PROMONTORY21_CHIP_H + +#include +#include +#include + +#define PROM21_MAX_PCIE_LANES 12 +#define PROM21_MAX_PCIE_CLKREQ 6 +#define PROM21_MAX_SATA_PORTS 4 +#define PROM21_XHCI_MAX_USB3_PORTS 6 +#define PROM21_XHCI_MAX_USB2_PORTS 12 + +#define PROM21_XHCI_DEVFN PCI_DEVFN(0xc, 0) +#define PROM21_SATA_DEVFN PCI_DEVFN(0xd, 0) + +struct prom21_sata_phy { + bool override; + uint8_t gen1_swing; + uint8_t gen2_swing; + uint8_t gen3_swing; + uint8_t gen1_emp_level; + uint8_t gen2_emp_level; + uint8_t gen3_emp_level; +}; + +struct prom21_usb3_phy { + bool override; + uint8_t gen1_swing; + uint8_t gen1_emp_level_en; + uint8_t gen1_emp_level; + uint8_t gen1_preshoot_en; + uint8_t gen1_preshoot; + uint8_t gen2_swing; + uint8_t gen2_cp0_emp_level_en; + uint8_t gen2_cp0_emp_level; + uint8_t gen2_cp0_preshoot_en; + uint8_t gen2_cp0_preshoot; + uint8_t gen2_cp13_emp_level_en; + uint8_t gen2_cp13_emp_level; + uint8_t gen2_cp13_preshoot_en; + uint8_t gen2_cp13_preshoot; + uint8_t gen2_cp14_emp_level_en; + uint8_t gen2_cp14_emp_level; + uint8_t gen2_cp14_preshoot_en; + uint8_t gen2_cp14_preshoot; + uint8_t gen2_cp15_emp_level_en; + uint8_t gen2_cp15_emp_level; + uint8_t gen2_cp15_preshoot_en; + uint8_t gen2_cp15_preshoot; + uint8_t gen2_cp16_emp_level_en; + uint8_t gen2_cp16_emp_level; + uint8_t gen2_cp16_preshoot_en; + uint8_t gen2_cp16_preshoot; +}; + +struct prom21_usb2_phy { + bool override; + uint8_t slew_rate; + uint8_t driving_current; + uint8_t termination; +}; + +enum prom21_xhci_port_gen { + XhciPortGenDefault = 0, + XhciPortGen1 = 1, + XhciPortGen2 = 2 +}; + +enum prom21_xhci_gen { + XhciGenDefault = 0, + XhciGen2x2 = 1, + XhciGen2x1 = 2 +}; + +enum prom21_boolean { + HwDefault = 0, + Disable = 1, + Enable = 2 +}; + +enum prom21_sata_mode { + SataAhci = 0, + SataRAID = 1 +}; + +enum prom21_clkreq_pin_select { + ClkreqPort0, + ClkreqPort1, + ClkreqPort2, + ClkreqPort3, + ClkreqPort4, + ClkreqPort5, + ClkreqPort6, + ClkreqPort7, + ClkreqPort8, + ClkreqPort9, + ClkreqPort10, + ClkreqPort11, + ClkreqUnused = 0xe +}; + +enum prom21_clkreq_mode { + ClkreqMode, + ClkAlwaysOn, + ClkAlwaysOff, + GpioMode +}; + +struct prom21_sata_config { + enum prom21_sata_mode sata_mode; + enum prom21_boolean aggresive_link_pm_cap; + enum prom21_boolean psc_cap; + enum prom21_boolean ssc_cap; + enum prom21_boolean hot_plug; + enum prom21_boolean cccs_cap; + enum prom21_boolean msi_cap; + uint8_t port_enable[PROM21_MAX_SATA_PORTS]; + enum prom21_boolean aggressive_dev_slp[PROM21_MAX_SATA_PORTS]; +}; + +struct prom21_usb_config { + enum prom21_xhci_gen usb3_gen; + enum prom21_xhci_port_gen port_gen[PROM21_XHCI_MAX_USB3_PORTS]; + enum prom21_boolean hw_lpm; + enum prom21_boolean dbc; +}; + +struct prom21_pcie_config { + enum prom21_boolean report_small_ltr; + bool gen1_swing_enable; + uint8_t pcie_gen1_swing[PROM21_MAX_PCIE_LANES]; + uint8_t eq_preset; + bool gpio_perst_enable; + enum prom21_boolean msi; + enum prom21_boolean msix; + enum prom21_clkreq_pin_select clkreq_pin_select[PROM21_MAX_PCIE_CLKREQ]; + enum prom21_clkreq_mode clkreq_mode[PROM21_MAX_PCIE_CLKREQ]; + enum prom21_boolean lane_reversal_en[PROM21_MAX_PCIE_LANES / 2]; + uint8_t port_target_speed[PROM21_MAX_PCIE_LANES]; +}; + +struct drivers_amd_promontory21_config { + enum prom21_boolean si_prog_enable; + struct prom21_usb3_phy usb3_phy[PROM21_XHCI_MAX_USB3_PORTS]; + struct prom21_usb2_phy usb2_phy[PROM21_XHCI_MAX_USB2_PORTS]; + struct prom21_sata_phy sata_phy[PROM21_MAX_SATA_PORTS]; + + struct prom21_usb_config usb; + struct prom21_sata_config sata; + struct prom21_pcie_config pcie; +}; + +#endif /* OPENSIL_PHOENIX_POC_MPIO_CHIP_H */ diff --git a/src/drivers/amd/promontory21/prom21_template.cb b/src/drivers/amd/promontory21/prom21_template.cb new file mode 100644 index 00000000000..387d2b3e55c --- /dev/null +++ b/src/drivers/amd/promontory21/prom21_template.cb @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# This file is a template. Mainboards should replicate this structure +# under the root port where the Promontory 21 chipset is located at. +# Placing the below topology under the root port is required for the driver +# to correctly parse the topology and apply settings based on the devicetree. + +chip drivers/amd/promontory21 + device pci 00.0 alias prom21_usp on # Upstream Port + ops amd_prom21_usp_ops + device pci 00.0 alias prom21_dsp_pcie_1 off ops amd_prom21_dsp_ops end + device pci 01.0 alias prom21_dsp_pcie_2 off ops amd_prom21_dsp_ops end + device pci 02.0 alias prom21_dsp_pcie_3 off ops amd_prom21_dsp_ops end + device pci 03.0 alias prom21_dsp_pcie_4 off ops amd_prom21_dsp_ops end + device pci 04.0 alias prom21_dsp_pcie_5 off ops amd_prom21_dsp_ops end + device pci 05.0 alias prom21_dsp_pcie_6 off ops amd_prom21_dsp_ops end + device pci 06.0 alias prom21_dsp_pcie_7 off ops amd_prom21_dsp_ops end + device pci 07.0 alias prom21_dsp_pcie_8 off ops amd_prom21_dsp_ops end + device pci 08.0 alias prom21_dsp_pcie_9 off ops amd_prom21_dsp_ops end + device pci 09.0 alias prom21_dsp_pcie_10 off ops amd_prom21_dsp_ops end + device pci 0a.0 alias prom21_dsp_pcie_11 off ops amd_prom21_dsp_ops end + device pci 0b.0 alias prom21_dsp_pcie_12 off ops amd_prom21_dsp_ops end + device pci 0c.0 alias prom21_dsp_xhci off + ops amd_prom21_dsp_ops + device pci 00.0 alias prom21_xhci off + ops xhci_pci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias prom_21_xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias prom21_usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias prom21_usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias prom21_usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias prom21_usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias prom21_usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias prom21_usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias prom21_usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias prom21_usb2_port8 off end + end + chip drivers/usb/acpi + device usb 2.8 alias prom21_usb2_port9 off end + end + chip drivers/usb/acpi + device usb 2.9 alias prom21_usb2_port10 off end + end + chip drivers/usb/acpi + device usb 2.a alias prom21_usb2_port11 off end + end + chip drivers/usb/acpi + device usb 2.b alias prom21_usb2_port12 off end + end + chip drivers/usb/acpi + device usb 3.0 alias prom21_usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias prom21_usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias prom21_usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias prom21_usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias prom21_usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias prom21_usb3_port6 off end + end + end + end + end + end + device pci 0d.0 alias prom21_dsp_sata off + ops amd_prom21_dsp_ops + device pci 00.0 alias prom21_sata off + ops prom21_sata_ops + end + end + end +end diff --git a/src/include/device/device.h b/src/include/device/device.h index ad9d9c5318f..5063e52d718 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -508,6 +508,14 @@ static inline bool is_root_device(const struct device *dev) (dev->upstream->dev == dev); } +static inline uint32_t pcidev_get_ssid(const struct device *dev) +{ + if (!dev) + return 0; + + return (dev->subsystem_vendor | ((uint32_t)dev->subsystem_device << 16)); +} + void enable_static_device(struct device *dev); void enable_static_devices(struct device *bus); void scan_smbus(struct device *bus); diff --git a/src/mainboard/msi/ms7e56/Kconfig b/src/mainboard/msi/ms7e56/Kconfig index 159894093c1..065722d5a30 100644 --- a/src/mainboard/msi/ms7e56/Kconfig +++ b/src/mainboard/msi/ms7e56/Kconfig @@ -5,18 +5,25 @@ if BOARD_MSI_PRO_B850_P config BOARD_SPECIFIC_OPTIONS def_bool y select BOARD_ROMSIZE_KB_32768 + select AZALIA_HDA_CODEC_SUPPORT select SOC_AMD_PHOENIX_AM5_OPENSIL + select SOC_AMD_COMMON_BLOCK_HDA select SOC_AMD_COMMON_BLOCK_USE_ESPI select SOC_AMD_COMMON_BLOCK_ESPI_RETAIN_PORT80_EN select SOC_AMD_COMMON_BLOCK_PSP_RPMC select SOC_AMD_COMMON_BLOCK_PSP_SMI select SPI_FLASH_FORCE_4_BYTE_ADDR_MODE select SUPERIO_NUVOTON_NCT6687D + select SMBIOS_TYPE41_PROVIDED_BY_DEVTREE select DRIVERS_UART_8250IO + select DRIVERS_AMD_PROMONTORY21 select HAVE_ACPI_TABLES select MEMORY_MAPPED_TPM select HAVE_X86_64_SUPPORT select USE_X86_64_SUPPORT + select IOAPIC_8BIT_ID + select IOAPIC_PREDEFINED_ID + select BOARD_HAS_MSI_ROMHOLE config FMDFILE default "src/mainboard/msi/ms7e56/board.fmd" @@ -33,6 +40,9 @@ config MAINBOARD_VENDOR config MAINBOARD_FAMILY default "Default string" +config MAINBOARD_VERSION + default "2.0" + config UART_FOR_CONSOLE default 0 @@ -86,4 +96,8 @@ config MRC_SETTINGS_CACHE_SIZE config ECAM_MMCONF_BASE_ADDRESS default 0xe0000000 +config MSI_ROMHOLE_TOOL_FLAGS + string + default "-DMSI_ROMHOLE_NO_FDP -DMSI_ROMHOLE_32BIT_LENGTHS -DMSI_ROMHOLE_BUV_SIZE=2048" + endif # BOARD_MSI_PRO_B850_P diff --git a/src/mainboard/msi/ms7e56/Makefile.mk b/src/mainboard/msi/ms7e56/Makefile.mk index 761c6a1c175..249ada920cd 100644 --- a/src/mainboard/msi/ms7e56/Makefile.mk +++ b/src/mainboard/msi/ms7e56/Makefile.mk @@ -4,7 +4,7 @@ bootblock-y += bootblock.c bootblock-y += early_gpio.c ramstage-y += gpio.c -ramstage-y += update_devicetree.c +ramstage-y += smbios.c ifneq ($(wildcard $(src)/mainboard/$(MAINBOARDDIR)/data*.apcb),) APCB_SOURCES = $(src)/mainboard/$(MAINBOARDDIR)/data.apcb @@ -13,3 +13,17 @@ APCB_SOURCES_68 = $(src)/mainboard/$(MAINBOARDDIR)/data_rec68.apcb else show_notices:: warn_no_apcb endif + +$(call src-to-obj,bootblock,$(dir)/msi_id.S): $(obj)/fmap_config.h $(obj)/build.h + +bootblock-y += msi_id.S + +$(obj)/msi_id.bin: $(obj)/bootblock/mainboard/$(MAINBOARDDIR)/msi_id.o + $(OBJCOPY_bootblock) -O binary $< $@ + +# The MSI ID must be in the last sectors of the image for the MSI FlashBIOS to +# detect it +$(call add_intermediate, add_msi_id, $(obj)/msi_id.bin) + @printf " WRITE MSI_ID\n" + $(CBFSTOOL) $< write -u -i 255 -r MSI_ID -f $(obj)/msi_id.bin + rm $(obj)/msi_id.bin diff --git a/src/mainboard/msi/ms7e56/acpi/mainboard.asl b/src/mainboard/msi/ms7e56/acpi/mainboard.asl new file mode 100644 index 00000000000..cb7d6f5a2d1 --- /dev/null +++ b/src/mainboard/msi/ms7e56/acpi/mainboard.asl @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +External (\_SB.PCI0.GP09, DeviceObj) +External (\_SB.PCI0.GP0A, DeviceObj) +External (\_SB.PCI0.GP0B, DeviceObj) +External (\_SB.PCI0.GP0C, DeviceObj) +External (\_SB.PCI0.GP11, DeviceObj) +External (\_SB.PCI0.GP12, DeviceObj) +External (\_SB.PCI0.GP11, DeviceObj) +External (\_SB.PCI0.GP41.XHC1, DeviceObj) +External (\_SB.PCI0.GP41.XHC2, DeviceObj) +External (\_SB.PCI0.GP41.AZAL, DeviceObj) +External (\_SB.PCI0.GP41.ACPD, DeviceObj) + +Scope (\_SB.PCI0) { + /* This device triggers automatic drivers and MSI utilities installation on Windows */ + Device (MSIV) { + Name (_HID, "MBAD0002") + Name (_UID, 1) + Method (_STA, 0, NotSerialized){ + Return (1) + } + } +} + +Scope (\_SB) +{ + Device (PWRB) + { + Name (_HID, EisaId ("PNP0C0C")) + Name (_UID, 0xAA) + Name (_STA, 0x0B) + } + + Name (S0IX, 0) + + /* + * Read dword from memory + * Arg0 - Base Address + * Arg1 - Offset + */ + Method (M04B, 2, Serialized) { + Local0 = 0 + If (Arg0 != 0) { + Local0 = Arg0 + Arg1 + OperationRegion (VARM, SystemMemory, Local0, 0x4) + Field (VARM, DWordAcc, NoLock, Preserve) { + VARR, 32, + } + Local0 = VARR + } + Return (Local0) + } + + /* + * Write dword to memory + * Arg0 - Base Address + * Arg1 - Offset + * Arg2 - Dword of data + */ + Method (M04E, 3, Serialized) { + If (Arg0 != 0) { + Local0 = Arg0 + Arg1 + OperationRegion (VARM, SystemMemory, Local0, 0x4) + Field (VARM, DWordAcc, NoLock, Preserve) { + VARR, 32, + } + VARR = Arg2 + } + } + + /* + * Write Memory + * Arg0 - Base Address + * Arg1 - Offset + * Arg2 - Start Bit + * Arg3 - Bit Width + * Arg4 - Value + */ + Method (M014, 5, Serialized) + { + Local1 = M04B (Arg0, Arg1) + Local5 = 0x7FFFFFFF + Local5 |= 0x80000000 + Local2 = (Arg2 + Arg3) + Local2 = (32 - Local2) + Local2 = (((Local5 << Local2) & Local5) >> Local2) + Local2 = ((Local2 >> Arg2) << Arg2) + Local3 = (Arg4 << Arg2) + Local4 = ((Local1 & (Local5 ^ Local2)) | Local3) + M04E (Arg0, Arg1, Local4) + } +} + +Scope (\_GPE) +{ + Method (_L02, 0, Serialized) + { + Notify (\_SB.PCI0.GP11, 0x00) + Notify (\_SB.PCI0.GP11, 0x02) + } + + Method (_L08, 0, NotSerialized) + { + Notify (\_SB.PCI0.GP09, 0x02) + Notify (\_SB.PCI0.GP0A, 0x02) + } + + Method (_L0E, 0, NotSerialized) + { + Notify (\_SB.PCI0.GP0C, 0x02) + Notify (\_SB.PWRB, 0x02) + } + + Method (_L0F, 0, NotSerialized) + { + Notify (\_SB.PCI0.GP0B, 0x02) + Notify (\_SB.PWRB, 0x02) + } + + Method (_L16, 0, NotSerialized) + { + Notify (\_SB.PCI0.GP12, Zero) + Notify (\_SB.PCI0.GP12, 0x02) + } +} + +Scope (\_SB.GPIO) +{ + + Method (_AEI, 0, Serialized) + { + Name (BUFF, ResourceTemplate () + { + GpioInt (Level, ActiveLow, ExclusiveAndWake, PullDefault, 0x01F4, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x000A + } + GpioInt (Edge, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0003 + } + GpioInt (Edge, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0020 + } + }) + Name (BUNP, ResourceTemplate () + { + GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0x1388, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0000 + } + GpioInt (Level, ActiveHigh, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x003D + } + GpioInt (Level, ActiveHigh, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x003E + } + GpioInt (Level, ActiveHigh, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x003A + } + GpioInt (Level, ActiveHigh, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x003B + } + GpioInt (Edge, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0002 + } + GpioInt (Edge, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0003 + } + GpioInt (Edge, ActiveLow, ExclusiveAndWake, PullNone, 0x0000, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x0009 + } + GpioInt (Level, ActiveLow, Exclusive, PullDefault, 0x01F4, + "\\_SB.GPIO", 0x00, ResourceConsumer, , ) { + 0x000A + } + }) + If (S0IX) { + Return (BUNP) + } Else { + Return (BUFF) + } + } + + Method (_EVT, 1, Serialized) + { + Switch (ToInteger (Arg0)) + { + Case (Zero) { Notify (\_SB.PWRB, 0x80) } + Case (0x3A) { + If (CondRefOf (\_SB.PCI0.GP41.XHC1)) + { + Notify (\_SB.PCI0.GP41.XHC1, 0x02) + } + } + Case (0x3B) { + If (CondRefOf (\_SB.PCI0.GP41.XHC2)) + { + Notify (\_SB.PCI0.GP41.XHC2, 0x02) + } + } + Case (0x3D) { + If (CondRefOf (\_SB.PCI0.GP41.AZAL)) + { + Notify (\_SB.PCI0.GP41.AZAL, 0x02) + } + } + Case (0x3E) { + If (CondRefOf (\_SB.PCI0.GP41.ACPD)) + { + Notify (\_SB.PCI0.GP41.ACPD, 0x02) + } + } + Case (0x02) + { + \_SB.M014 (0xFED80200, 0, 0, 32, 0x0100) + If (CondRefOf (\_GPE._L08)) + { + \_GPE._L08 () + } + } + Case (0x03) + { + + \_SB.M014 (0xFED80200, 0, 0, 32, 0x04) + If (CondRefOf (\_GPE._L02)) + { + \_GPE._L02 () + } + } + Case (0x20) + { + \_SB.M014 (0xFED80200, 0, 0, 32, 0x00800000) + If (CondRefOf (\_GPE._L02)) + { + \_GPE._L02 () + } + } + Case (0x09) + { + If (CondRefOf (\_GPE._L16)) + { + \_GPE._L16 () + } + } + } + } +} diff --git a/src/mainboard/msi/ms7e56/acpi/superio.asl b/src/mainboard/msi/ms7e56/acpi/superio.asl new file mode 100644 index 00000000000..6c2ae3d9d71 --- /dev/null +++ b/src/mainboard/msi/ms7e56/acpi/superio.asl @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define SUPERIO_DEV SIO0 +#define SUPERIO_PNP_BASE 0x4e +#define NCT6687D_SHOW_SP1 +#define NCT6687D_SHOW_EC + +#include diff --git a/src/mainboard/msi/ms7e56/board.fmd b/src/mainboard/msi/ms7e56/board.fmd index 4f60ca47e42..261da79416b 100644 --- a/src/mainboard/msi/ms7e56/board.fmd +++ b/src/mainboard/msi/ms7e56/board.fmd @@ -1,10 +1,17 @@ FLASH 32M { BIOS 16M { - COREBOOT(CBFS) FMAP 4K - PSP_NVRAM 128K - PSP_RPMC_NVRAM 256K + COREBOOT(CBFS) SMMSTORE(PRESERVE) 512K - RW_MRC_CACHE 1M } + RW_MRC_CACHE 1M + PSP_NVRAM 128K + PSP_RPMC_NVRAM 256K + UNUSED + BPA(PRESERVE)@0x1B50000 320K + UNUSED2 + # ROMHOLE must be at flash offset 0x1BE0000 + ROMHOLE(PRESERVE)@0x1BE0000 128K + UNUSED3 + MSI_ID 4K } diff --git a/src/mainboard/msi/ms7e56/bootblock.c b/src/mainboard/msi/ms7e56/bootblock.c index a32df252723..b00ab6bc2e6 100644 --- a/src/mainboard/msi/ms7e56/bootblock.c +++ b/src/mainboard/msi/ms7e56/bootblock.c @@ -1,8 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include +#include #include #include +#include #include #include #include @@ -16,20 +20,64 @@ #define EC_IO_BASE 0xa20 -void bootblock_mainboard_early_init(void) +void mb_set_up_early_espi(void) { + espi_switch_to_spi1_pads(); mainboard_program_early_gpios(); +} - espi_switch_to_spi1_pads(); +static void post_espi_init(void) +{ + volatile void *espi_base = (void *)lpc_get_spibase() + ESPI_OFFSET_FROM_BAR; + uint32_t value; + + /* Initialzie eSPI watchdog timer */ + value = read32(espi_base + ESPI_GLOBAL_CONTROL_0); + value &= ~(ESPI_WDG_CNT_MASK | ESPI_AL_IDLE_TIMER_MASK); + value |= (ESPI_AL_IDLE_TIMER_MASK | (0x1400 << ESPI_WDG_CNT_SHIFT)); + write32(espi_base + ESPI_GLOBAL_CONTROL_0, value); + + write32(espi_base + ESPI_GLOBAL_CONTROL_0, + read32(espi_base + ESPI_GLOBAL_CONTROL_0) | ESPI_WDG_EN); + write32(espi_base + ESPI_GLOBAL_CONTROL_0, + read32(espi_base + ESPI_GLOBAL_CONTROL_0) | ESPI_WAIT_CHKEN); + + value = read32(espi_base + ESPI_GLOBAL_CONTROL_0); + value &= ~ESPI_WAIT_CNT_MASK; + value |= ESPI_WAIT_CNT_MASK; + value |= (1 << 31); // set reserved bit as vendor BIOS does + write32(espi_base + ESPI_GLOBAL_CONTROL_0, value); + + /* Program RX Virtual Wires */ + write32(espi_base + ESPI_RXVW_INDEX, 0x00040506); + write32(espi_base + ESPI_RXVW_MISC_CNTL, 0x00000007); + + value = read32(espi_base + ESPI_GLOBAL_CONTROL_1); + value |= ESPI_REQ_NOTWITH_VW_REQ; + write32(espi_base + ESPI_GLOBAL_CONTROL_1, value); + + /* Clear and enable interrupts */ + value = read32(espi_base + ESPI_SLAVE0_INT_STS); + if (value) + write32(espi_base + ESPI_SLAVE0_INT_STS, value); + + write32(espi_base + ESPI_SLAVE0_INT_EN, UINT32_MAX); +} + +void bootblock_mainboard_early_init(void) +{ + post_espi_init(); /* Replicate vendor settings for multi-function pins in global config LDN */ nuvoton_pnp_enter_conf_state(GPIO_DEV); + pnp_write_config(GPIO_DEV, 0x10, 0xff); // IRQ8-15 level triggered, low + pnp_write_config(GPIO_DEV, 0x11, 0xff); // IRQ0-7 level triggered, low pnp_write_config(GPIO_DEV, 0x13, 0xff); // IRQ8-15 level triggered, low pnp_write_config(GPIO_DEV, 0x14, 0xff); // IRQ0-7 level triggered, low /* Below are multi-pin function */ pnp_write_config(GPIO_DEV, 0x15, 0x0a); - pnp_write_config(GPIO_DEV, 0x1a, 0x80); + pnp_write_config(GPIO_DEV, 0x1a, 0x82); pnp_write_config(GPIO_DEV, 0x1b, 0x02); pnp_write_config(GPIO_DEV, 0x1d, 0x00); pnp_write_config(GPIO_DEV, 0x1e, 0xa2); @@ -57,8 +105,8 @@ void bootblock_mainboard_early_init(void) /* Configure yellow and green LED */ pnp_write_config(POWER_DEV, 0xe7, 0xa0); pnp_write_config(POWER_DEV, 0xe8, 0x07); -// pnp_set_logical_device(P80_UART_DEV); -// pnp_write_config(P80_UART_DEV, 0xe5, 0x0f); + pnp_set_logical_device(P80_UART_DEV); + pnp_write_config(P80_UART_DEV, 0xe5, 0x0f); /* Configure EC */ pnp_set_logical_device(EC_DEV); diff --git a/src/mainboard/msi/ms7e56/data.apcb b/src/mainboard/msi/ms7e56/data.apcb index 3147362a84e..8712aced369 100644 Binary files a/src/mainboard/msi/ms7e56/data.apcb and b/src/mainboard/msi/ms7e56/data.apcb differ diff --git a/src/mainboard/msi/ms7e56/data_rec.apcb b/src/mainboard/msi/ms7e56/data_rec.apcb index 30dd75fc128..2e4d805dd08 100644 Binary files a/src/mainboard/msi/ms7e56/data_rec.apcb and b/src/mainboard/msi/ms7e56/data_rec.apcb differ diff --git a/src/mainboard/msi/ms7e56/data_rec68.apcb b/src/mainboard/msi/ms7e56/data_rec68.apcb index 3147362a84e..7a2af0293ed 100644 Binary files a/src/mainboard/msi/ms7e56/data_rec68.apcb and b/src/mainboard/msi/ms7e56/data_rec68.apcb differ diff --git a/src/mainboard/msi/ms7e56/devicetree.cb b/src/mainboard/msi/ms7e56/devicetree.cb index 586b69f44e1..bbb95610d7d 100644 --- a/src/mainboard/msi/ms7e56/devicetree.cb +++ b/src/mainboard/msi/ms7e56/devicetree.cb @@ -3,6 +3,7 @@ chip soc/amd/phoenix # Set FADT Configuration register "common_config.fadt_boot_arch" = "ACPI_FADT_LEGACY_DEVICES" + register "common_config.fadt_flags" = "ACPI_FADT_SLEEP_BUTTON" # See table 5-34 ACPI 6.3 spec register "common_config.espi_config" = "{ .std_io_decode_bitmap = ESPI_DECODE_IO_0x80_EN | ESPI_DECODE_IO_0X2E_0X2F_EN | ESPI_DECODE_IO_0X60_0X64_EN, @@ -39,10 +40,20 @@ chip soc/amd/phoenix .vw_ch_en = 1, .oob_ch_en = 1, .flash_ch_en = 1, + .irq_mask = 0xffe107, + .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_LOW(4), }" register "s0ix_enable" = "false" + register "gpp_clk_config[0]" = "GPP_CLK_ON" + register "gpp_clk_config[1]" = "GPP_CLK_ON" + register "gpp_clk_config[2]" = "GPP_CLK_ON" + register "gpp_clk_config[3]" = "GPP_CLK_ON" + register "gpp_clk_config[4]" = "GPP_CLK_ON" + register "gpp_clk_config[5]" = "GPP_CLK_ON" + register "gpp_clk_config[6]" = "GPP_CLK_ON" + register "pspp_policy" = "DXIO_PSPP_DISABLED" register "usb_phy_custom" = "true" @@ -200,6 +211,8 @@ chip soc/amd/phoenix register "usb3_oc_pins[3]" = "{ 0x1, 0xf, 0xf, 0xf }" device domain 0 on + subsystemid 0x1462 0x7e56 inherit + device ref iommu on end # PCIE_E1: x8 PCIe slot, DXIO lanes 0-7 @@ -207,14 +220,18 @@ chip soc/amd/phoenix register "type" = "IFTYPE_PCIE" register "start_lane" = "0" register "end_lane" = "7" - device ref gpp_bridge_1_1 on end + device ref gpp_bridge_1_1 on + smbios_slot_desc "SlotTypePciExpressGen4x16" "SlotLengthLong" "PCIE_E1" "SlotDataBusWidth8X" + end end # M2_1: x4 M.2 slot, DXIO lanes 16-19 chip drivers/amd/opensil/mpio register "type" = "IFTYPE_PCIE" register "start_lane" = "16" register "end_lane" = "19" - device ref gpp_bridge_1_2 on end + device ref gpp_bridge_1_2 on + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M2_1" "SlotDataBusWidth4X" + end end # Promontory B850 chipset: x4 link, DXIO lanes 20-23 chip drivers/amd/opensil/mpio @@ -222,19 +239,426 @@ chip soc/amd/phoenix register "start_lane" = "20" register "end_lane" = "23" register "sb_link" = "1" - device ref gpp_bridge_2_1 on end + device ref gpp_bridge_2_1 on + chip drivers/amd/promontory21 + device pci 00.0 alias prom21_usp on # Upstream Port + ops amd_prom21_usp_ops + + register "pcie.report_small_ltr" = "Enable" + register "pcie.gen1_swing_enable" = "true" + + register "pcie.pcie_gen1_swing" = "{ + 0x3f, 0x3f, 0x3f, 0x3f, + 0x13, 0x13, 0x13, 0x13, + 0x3f, 0x3f, 0x3f, 0x3f + }" + + register "pcie.clkreq_pin_select" = "{ + ClkreqPort2, + ClkreqPort0, + ClkreqPort8, + ClkreqPort10, + ClkreqPort11, + ClkreqPort3 + }" + + register "pcie.port_target_speed[0]" = "4" + register "pcie.port_target_speed[2]" = "3" + register "pcie.port_target_speed[3]" = "3" + register "pcie.port_target_speed[8]" = "4" + register "pcie.port_target_speed[10]" = "3" + register "pcie.port_target_speed[11]" = "3" + + register "pcie.msi" = "Enable" + register "pcie.msix" = "Enable" + + device pci 00.0 alias prom21_dsp_pcie_1 on # PCI_E3 + ops amd_prom21_dsp_ops + smbios_slot_desc "SlotTypePciExpressGen4x16" "SlotLengthLong" "PCI_E3" "SlotDataBusWidth4X" + end + device pci 01.0 alias prom21_dsp_pcie_2 off + ops amd_prom21_dsp_ops + end + device pci 02.0 alias prom21_dsp_pcie_3 on # PCI_E2 + ops amd_prom21_dsp_ops + smbios_slot_desc "SlotTypePciExpressGen3X16" "SlotLengthLong" "PCI_E2" "SlotDataBusWidth1X" + end + device pci 03.0 alias prom21_dsp_pcie_4 on # PCI_E4 + ops amd_prom21_dsp_ops + smbios_slot_desc "SlotTypePciExpressGen3X16" "SlotLengthLong" "PCI_E4" "SlotDataBusWidth1X" + end + device pci 04.0 alias prom21_dsp_pcie_5 off # used as SATA + ops amd_prom21_dsp_ops + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M2_3" "SlotDataBusWidth4X" + end + device pci 05.0 alias prom21_dsp_pcie_6 off # used as SATA + ops amd_prom21_dsp_ops + end + device pci 06.0 alias prom21_dsp_pcie_7 off # used as SATA + ops amd_prom21_dsp_ops + end + device pci 07.0 alias prom21_dsp_pcie_8 off # used as SATA + ops amd_prom21_dsp_ops + end + device pci 08.0 alias prom21_dsp_pcie_9 on # M2_3 + ops amd_prom21_dsp_ops + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M2_3" "SlotDataBusWidth4X" + end + device pci 09.0 alias prom21_dsp_pcie_10 off + ops amd_prom21_dsp_ops + end + device pci 0a.0 alias prom21_dsp_pcie_11 on # Ethernet Realtek + ops amd_prom21_dsp_ops + device pci 00.0 on + smbios_dev_info 1 "Onboard LAN" + end + end + device pci 0b.0 alias prom21_dsp_pcie_12 on # WiFi Qualcomm + ops amd_prom21_dsp_ops + device pci 00.0 on + smbios_dev_info 1 "Onboard WIFI" + end + end + device pci 0c.0 alias prom21_dsp_xhci on + ops amd_prom21_dsp_ops + + device pci 00.0 alias prom21_xhci on + ops xhci_pci_ops + + register "usb.hw_lpm" = "Enable" + register "usb.dbc" = "Enable" + register "usb.usb3_gen" = "XhciGen2x2" + register "usb.port_gen" = "{ + XhciPortGen1, + XhciPortGen1, + XhciPortGen1, + XhciPortGen1, + XhciPortGen1 + }" + + register "usb3_phy[0]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + register "usb3_phy[1]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + register "usb3_phy[2]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + register "usb3_phy[3]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + register "usb3_phy[4]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + register "usb3_phy[5]" = "{ + .override = true, + .gen1_swing = 0xf, + .gen1_emp_level_en = 0x1, + .gen1_emp_level = 0x3, + .gen1_preshoot_en = 0x0, + .gen1_preshoot = 0x0, + .gen2_swing = 0xc, + .gen2_cp0_emp_level_en = 0x1, + .gen2_cp0_emp_level = 0x3, + .gen2_cp0_preshoot_en = 0x1, + .gen2_cp0_preshoot = 0x1, + .gen2_cp13_emp_level_en = 0x0, + .gen2_cp13_emp_level = 0x3, + .gen2_cp13_preshoot_en = 0x1, + .gen2_cp13_preshoot = 0x1, + .gen2_cp14_emp_level_en = 0x1, + .gen2_cp14_emp_level = 0x3, + .gen2_cp14_preshoot_en = 0x0, + .gen2_cp14_preshoot = 0x1, + .gen2_cp15_emp_level_en = 0x1, + .gen2_cp15_emp_level = 0x3, + .gen2_cp15_preshoot_en = 0x1, + .gen2_cp15_preshoot = 0x1, + .gen2_cp16_emp_level_en = 0x0, + .gen2_cp16_emp_level = 0x3, + .gen2_cp16_preshoot_en = 0x0, + .gen2_cp16_preshoot = 0x1 + }" + + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias prom_21_xhci_root_hub on + chip drivers/usb/acpi + register "desc" = ""JUSB3"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.0 alias prom21_usb2_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB3"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.1 alias prom21_usb2_port2 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB4"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.2 alias prom21_usb2_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB4"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.3 alias prom21_usb2_port4 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSBC5"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.4 alias prom21_usb2_port5 on end + end + chip drivers/usb/acpi + device usb 2.5 alias prom21_usb2_port6 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB1"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.6 alias prom21_usb2_port7 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB1"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.7 alias prom21_usb2_port8 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB2"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.8 alias prom21_usb2_port9 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB2"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.9 alias prom21_usb2_port10 on end + end + chip drivers/usb/acpi + register "desc" = ""WIFI/BT"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.a alias prom21_usb2_port11 on end + end + chip drivers/usb/acpi + register "desc" = ""MSI MYSTIC LIGHT"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 2.b alias prom21_usb2_port12 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB3"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 3.0 alias prom21_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB3"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 3.1 alias prom21_usb3_port2 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB4"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 3.2 alias prom21_usb3_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSB4"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 3.3 alias prom21_usb3_port4 on end + end + chip drivers/usb/acpi + register "desc" = ""JUSBC5"" + register "type" = "UPC_TYPE_INTERNAL" + device usb 3.4 alias prom21_usb3_port5 on end + end + chip drivers/usb/acpi + device usb 3.5 alias prom21_usb3_port6 off end + end + end + end + end + end + device pci 0d.0 alias prom21_dsp_sata on + ops amd_prom21_dsp_ops + + device pci 00.0 alias prom21_sata on + ops prom21_sata_ops + + register "sata.port_enable" = "{ 1, 1, 1, 1 }" + register "sata.aggressive_dev_slp" = "{ + Disable, + Disable, + Disable, + Disable + }" + + register "sata.aggresive_link_pm_cap" = "Enable" + register "sata.psc_cap" = "Enable" + register "sata.ssc_cap" = "Enable" + register "sata.hot_plug" = "Disable" + register "sata.cccs_cap" = "Disable" + register "sata.msi_cap" = "Enable" + end + end + end + end + end end # M2_2: x4 M.2 slot, DXIO lanes 24-27 chip drivers/amd/opensil/mpio register "type" = "IFTYPE_PCIE" register "start_lane" = "24" register "end_lane" = "27" - device ref gpp_bridge_2_2 on end + device ref gpp_bridge_2_2 on + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M2_2" "SlotDataBusWidth4X" + end end device ref gpp_bridge_a on # Internal GPP Bridge 0 to Bus A - device ref gfx on end # Internal GPU (GFX) - device ref gfx_hda on end # Display HD Audio Controller (GFXAZ) + device ref gfx on + smbios_dev_info 1 "Onboard IGD" + chip drivers/amd/opensil/mpio + register "type" = "IFTYPE_DDI" + register "ddi_connector" = "ConnHDMI" + register "aux" = "DdiAux1" + register "hdp" = "DdiHdp1" + device generic 0 on end + end + end # Internal GPU (GFX) + device ref gfx_hda on + smbios_dev_info 1 "IGD Audio" + end # Display HD Audio Controller (GFXAZ) device ref crypto on end # Crypto Coprocessor device ref xhci_0 on chip drivers/usb/acpi @@ -280,7 +704,12 @@ chip soc/amd/phoenix end end end - device ref acp on end # Audio Processor (ACP) + device ref hda on + smbios_dev_info 2 "Onboard Audio" + end + end + device ref gpp_bridge_b on # Internal GPP Bridge 1 to Bus B + device ref ipu on end end device ref gpp_bridge_c on # Internal GPP Bridge 2 to Bus C device ref usb4_xhci_0 on @@ -503,8 +932,6 @@ chip soc/amd/phoenix end end - device ref i2c_0 on end - device ref i2c_1 on end - device ref i2c_2 on end - device ref i2c_3 on end + device ref i2c_0 hidden end + device ref i2c_1 hidden end end diff --git a/src/mainboard/msi/ms7e56/dsdt.asl b/src/mainboard/msi/ms7e56/dsdt.asl index 7b8982a645c..a1df208cc91 100644 --- a/src/mainboard/msi/ms7e56/dsdt.asl +++ b/src/mainboard/msi/ms7e56/dsdt.asl @@ -13,4 +13,13 @@ DefinitionBlock ( #include #include + + + Scope (\_SB.PCI0.LPCB) + { + #include "acpi/superio.asl" + } + + #include "acpi/mainboard.asl" + #include } diff --git a/src/mainboard/msi/ms7e56/early_gpio.c b/src/mainboard/msi/ms7e56/early_gpio.c index af71f7e2852..50df3b9d669 100644 --- a/src/mainboard/msi/ms7e56/early_gpio.c +++ b/src/mainboard/msi/ms7e56/early_gpio.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include "gpio.h" @@ -7,39 +8,33 @@ static const struct soc_amd_gpio gpio_set_stage_reset[] = { /* TPM CS */ - PAD_NF(GPIO_29, SPI_TPM_CS_L, PULL_NONE), + PAD_NF(GPIO_29, SPI_TPM_CS_L, PULL_UP), /* ESPI_CS_L */ - PAD_NF(GPIO_30, ESPI_CS_L, PULL_NONE), + PAD_NF(GPIO_30, ESPI_CS_L, PULL_UP), /* ESPI_SOC_CLK */ - PAD_NF(GPIO_77, SPI1_CLK, PULL_NONE), + PAD_NF(GPIO_77, SPI1_CLK, PULL_DOWN), /* ESPI_DATA0 */ - PAD_NF(GPIO_81, SPI1_DAT0, PULL_NONE), + PAD_NF(GPIO_81, SPI1_DAT0, PULL_UP), /* ESPI_DATA1 */ - PAD_NF(GPIO_80, SPI1_DAT1, PULL_NONE), + PAD_NF(GPIO_80, SPI1_DAT1, PULL_UP), /* ESPI_DATA2 */ - PAD_NF(GPIO_68, SPI1_DAT2, PULL_NONE), + PAD_NF(GPIO_68, SPI1_DAT2, PULL_UP), /* ESPI_DATA3 */ - PAD_NF(GPIO_69, SPI1_DAT3, PULL_NONE), + PAD_NF(GPIO_69, SPI1_DAT3, PULL_UP), /* ESPI_ALERT_L */ - PAD_NF(GPIO_22, ESPI_ALERT_D1, PULL_NONE), - /* TPM IRQ */ - // PAD_INT(GPIO_130, PULL_NONE, EDGE_LOW, STATUS_DELIVERY), + PAD_NF(GPIO_22, ESPI_ALERT_D1, PULL_UP), + /* ESPI_RESET_L */ + PAD_NF(GPIO_21, ESPI_RESET_L, PULL_UP), /* SPI_ROM_REQ */ - PAD_NF(GPIO_67, SPI_ROM_REQ, PULL_NONE), + PAD_NF(GPIO_67, SPI_ROM_REQ, PULL_UP), /* SPI_ROM_GNT */ - PAD_NF(GPIO_76, SPI_ROM_GNT, PULL_NONE), - /* KBRST_L */ - PAD_NF(GPIO_21, KBRST_L, PULL_NONE), + PAD_NF(GPIO_76, SPI_ROM_GNT, PULL_DOWN), + /* SPI1_CS3_L */ + PAD_NF(GPIO_79, SPI1_CS3_L, PULL_UP), /* Deassert PCIe Reset lines */ /* PCIE_RST0_L */ PAD_NFO(GPIO_26, PCIE_RST0_L, HIGH), - /* PCIE_RST1_L */ - PAD_NFO(GPIO_27, PCIE_RST1_L, HIGH), - /* M2_SSD0_RST_L */ - PAD_GPO(GPIO_78, HIGH), - /* M2_SSD1_RST_L */ - PAD_GPO(GPIO_79, HIGH), /* I2C0 SCL */ PAD_NF(GPIO_145, I2C0_SCL, PULL_NONE), @@ -49,14 +44,14 @@ static const struct soc_amd_gpio gpio_set_stage_reset[] = { PAD_NF(GPIO_147, I2C1_SCL, PULL_NONE), /* I2C1 SDA */ PAD_NF(GPIO_148, I2C1_SDA, PULL_NONE), - /* I2C2_SCL */ - PAD_NF(GPIO_113, I2C2_SCL, PULL_NONE), - /* I2C2_SDA */ - PAD_NF(GPIO_114, I2C2_SDA, PULL_NONE), - /* I2C3_SCL */ - PAD_NF(GPIO_19, I2C3_SCL, PULL_NONE), - /* I2C3_SDA */ - PAD_NF(GPIO_20, I2C3_SDA, PULL_NONE), + /* SMBUS0_SCL */ + PAD_NF(GPIO_113, SMBUS0_SCL, PULL_NONE), + /* SMBUS0_SDA */ + PAD_NF(GPIO_114, SMBUS0_SDA, PULL_NONE), + /* SMBUS1_SCL */ + PAD_NF(GPIO_19, SMBUS1_SCL, PULL_NONE), + /* SMBUS1_SDA */ + PAD_NF(GPIO_20, SMBUS1_SDA, PULL_NONE), }; void mainboard_program_early_gpios(void) diff --git a/src/mainboard/msi/ms7e56/gpio.c b/src/mainboard/msi/ms7e56/gpio.c index 5a09ba578fd..481993a4229 100644 --- a/src/mainboard/msi/ms7e56/gpio.c +++ b/src/mainboard/msi/ms7e56/gpio.c @@ -6,8 +6,25 @@ /* GPIO pins used by coreboot should be initialized in bootblock */ static const struct soc_amd_gpio gpio_table[] = { - /* S0A3 */ - PAD_NF(GPIO_10, S0A3_GPIO, PULL_NONE) + PAD_GPI(GPIO_2, PULL_UP), + PAD_INT(GPIO_3, PULL_UP, LEVEL_LOW, STATUS_DELIVERY), + PAD_GPO(GPIO_5, HIGH), + PAD_GPO(GPIO_6, HIGH), + PAD_GPO(GPIO_7, HIGH), + PAD_GPO(GPIO_8, LOW), + PAD_GPI(GPIO_9, PULL_NONE), + PAD_NF(GPIO_10, S0A3_GPIO, PULL_UP), + PAD_NF(GPIO_11, BLINK, PULL_UP), + PAD_GPI(GPIO_12, PULL_UP), + PAD_GPI(GPIO_18, PULL_UP), + PAD_GPI(GPIO_23, PULL_UP), + PAD_GPI(GPIO_27, PULL_UP), + PAD_INT(GPIO_32, PULL_NONE, LEVEL_LOW, STATUS_DELIVERY), + PAD_GPO(GPIO_40, HIGH), + PAD_GPI(GPIO_42, PULL_UP), + PAD_GPI(GPIO_78, PULL_UP), + PAD_NF(GPIO_91, SPKR, PULL_NONE), + PAD_GPI(GPIO_115, PULL_UP), }; void mainboard_program_gpios(void) diff --git a/src/mainboard/msi/ms7e56/hda_verb.c b/src/mainboard/msi/ms7e56/hda_verb.c new file mode 100644 index 00000000000..105cb92709a --- /dev/null +++ b/src/mainboard/msi/ms7e56/hda_verb.c @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#define AC_VERB_SET_PROC_COEF 0x400 +#define AC_VERB_SET_COEF_INDEX 0x500 + +#define ALC_WRITE_COEF(codec, idx, val) \ + AZALIA_VERB_12B(codec, 0x20, AC_VERB_SET_COEF_INDEX, (idx) & 0xffff), \ + AZALIA_VERB_12B(codec, 0x20, AC_VERB_SET_PROC_COEF, (val) & 0xffff) \ + +static const u32 realtek_alc897_verbs[] = { + AZALIA_RESET(0x1), + AZALIA_SUBVENDOR(0, 0x14629e56), + AZALIA_PIN_CFG(0, 0x11, 0x4033c040), + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x14, 0x01011010), + AZALIA_PIN_CFG(0, 0x15, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x16, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x17, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x18, 0x01a11040), + AZALIA_PIN_CFG(0, 0x19, 0x02a19050), + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1b, 0x02214020), + AZALIA_PIN_CFG(0, 0x1c, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x4027c26b), + AZALIA_PIN_CFG(0, 0x1e, 0x01451130), + AZALIA_PIN_CFG(0, 0x1f, AZALIA_PIN_CFG_NC(0)), + + /* TODO: confirm below */ + // ALC_WRITE_COEF(0, 0x3b, 0x80), + // ALC_WRITE_COEF(0, 0x39, 0x4031), + + // ALC_WRITE_COEF(0, 0x13, 0x53), + // ALC_WRITE_COEF(0, 0x30, 0x92D1), + + // ALC_WRITE_COEF(0, 0x21, 0x00), + // ALC_WRITE_COEF(0, 0x23, 0x00), + + // ALC_WRITE_COEF(0, 0x25, 0x00), + // ALC_WRITE_COEF(0, 0x27, 0x00), + + // ALC_WRITE_COEF(0, 0x29, 0x00), + // ALC_WRITE_COEF(0, 0x2A, 0x1640), + + // ALC_WRITE_COEF(0, 0x2B, 0x1640), + // ALC_WRITE_COEF(0, 0x21, 0xC00), + + // ALC_WRITE_COEF(0, 0x23, 0xC00), + // ALC_WRITE_COEF(0, 0x25, 0xC00), + + // ALC_WRITE_COEF(0,0x027, 0xC00), + // ALC_WRITE_COEF(0,0x029, 0xC00), + + // ALC_WRITE_COEF(0, 0x2A, 0x1641), + // ALC_WRITE_COEF(0, 0x2B, 0x1641), + + // ALC_WRITE_COEF(0, 0x30, 0x9251), + // ALC_WRITE_COEF(0, 0x2A, 0x1649), + + // ALC_WRITE_COEF(0, 0x2B, 0x1649), + // ALC_WRITE_COEF(0, 0xC, 0x3F06), + + // ALC_WRITE_COEF(0, 0x7, 0xF808), + // ALC_WRITE_COEF(0, 0x7, 0xF808), +}; + +static const u32 amd_display_audio_verbs[] = { + AZALIA_RESET(0x1), + AZALIA_SUBVENDOR(0, 0x00aa0100), + AZALIA_PIN_CFG(0, 0x03, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_DIGITAL_DISPLAY, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0 + )), + AZALIA_PIN_CFG(0, 0x05, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_DIGITAL_DISPLAY, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0 + )), + AZALIA_PIN_CFG(0, 0x07, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_DIGITAL_DISPLAY, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0 + )), + AZALIA_PIN_CFG(0, 0x09, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_DIGITAL_DISPLAY, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0 + )), + AZALIA_PIN_CFG(0, 0x0b, AZALIA_PIN_DESC( + AZALIA_NC, + AZALIA_DIGITAL_DISPLAY, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0 + )) +}; + +const u32 pc_beep_verbs[] = {}; + +struct azalia_codec mainboard_azalia_codecs[] = { + { + .name = "Realtek ALC897", + .vendor_id = 0x10ec0897, + .subsystem_id = 0x14629e56, + .address = 0, + .verbs = realtek_alc897_verbs, + .verb_count = ARRAY_SIZE(realtek_alc897_verbs), + }, + { + .name = "AMD Display Audio (HDMI/DP)", + .vendor_id = 0x1002aa01, + .subsystem_id = 0x00aa0100, + .address = 0, + .verbs = amd_display_audio_verbs, + .verb_count = ARRAY_SIZE(amd_display_audio_verbs), + }, + { /* terminator */ } +}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/msi/ms7e56/mainboard.c b/src/mainboard/msi/ms7e56/mainboard.c index b9c06cf6bd7..a46ab023739 100644 --- a/src/mainboard/msi/ms7e56/mainboard.c +++ b/src/mainboard/msi/ms7e56/mainboard.c @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include +#include #include +#include #include #include "gpio.h" -#include "update_devicetree.h" /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is accessed via I/O ports 0xc00/0xc01. */ @@ -22,26 +24,28 @@ * 9: acpi <- soc/amd/common/acpi/lpc.asl */ static const struct fch_irq_routing fch_irq_map[] = { - { PIRQ_A, 10, 0x10 }, - { PIRQ_B, 11, 0x11 }, - { PIRQ_C, 11, 0x12 }, - { PIRQ_D, 10, 0x13 }, - { PIRQ_E, 10, 0x14 }, - { PIRQ_F, 11, 0x15 }, - { PIRQ_G, 11, 0x16 }, - { PIRQ_H, 10, 0x17 }, + { PIRQ_A, 0x03, 0x10 }, + { PIRQ_B, 0x04, 0x11 }, + { PIRQ_C, 0x05, 0x12 }, + { PIRQ_D, 0x06, 0x13 }, + { PIRQ_E, 0x0a, 0x14 }, + { PIRQ_F, 0x0b, 0x15 }, + { PIRQ_G, 0x0e, 0x16 }, + { PIRQ_H, 0x0f, 0x17 }, { PIRQ_SCI, ACPI_SCI_IRQ, ACPI_SCI_IRQ }, + { PIRQ_SD, PIRQ_NC, 0x10 }, { PIRQ_SDIO, PIRQ_NC, 0x10 }, { PIRQ_GPIO, 0x07, 0x07 }, - { PIRQ_I2C0, 0x0a, 0x0a }, - { PIRQ_I2C1, 0x0b, 0x0b }, - { PIRQ_I2C2, 0x0e, 0x0e }, - { PIRQ_I2C3, 0x0f, 0x06 }, - { PIRQ_UART0, 4, 0x03 }, - { PIRQ_UART1, 3, 0x0e }, - { PIRQ_UART2, 4, 0x05 }, - { PIRQ_UART3, 3, 0x0f }, - { PIRQ_UART4, 4, 0x10 }, + { PIRQ_EMMC, PIRQ_NC, 0x05 }, + { PIRQ_I2C0, PIRQ_NC, 0x03 }, + { PIRQ_I2C1, PIRQ_NC, PIRQ_NC }, + { PIRQ_I2C2, PIRQ_NC, PIRQ_NC }, + { PIRQ_I2C3, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART0, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART1, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART2, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART3, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART4, PIRQ_NC, PIRQ_NC }, /* The MISC registers are not interrupt numbers */ { PIRQ_MISC, 0xfa, 0x00 }, { PIRQ_MISC0, 0x91, 0x00 }, @@ -56,13 +60,52 @@ const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) return fch_irq_map; } +static const char *hda_acpi_name(const struct device *dev) +{ + return "AZAL"; +} + +static const char *gfx_hda_acpi_name(const struct device *dev) +{ + return "HDAU"; +} + +static const char *crypto_acpi_name(const struct device *dev) +{ + return "APSP"; +} + +#define SET_AUDIO_DEV_OPS(dev) \ + struct device *dev = (struct device *)DEV_PTR(dev); \ + if (is_dev_enabled(dev)) { \ + (dev)->ops = &phx_ ## dev ## _audio_ops; \ + (dev)->ops->acpi_name = dev ## _acpi_name; \ + (dev)->ops->acpi_fill_ssdt = acpi_device_write_pci_dev; \ + } + +static struct device_operations phx_hda_audio_ops; +static struct device_operations phx_gfx_hda_audio_ops; + static void mainboard_init(void *chip_info) { + struct device *psp = (struct device *)DEV_PTR(crypto); + mainboard_program_gpios(); - mainboard_update_devicetree_opensil(); + memcpy(&phx_hda_audio_ops, &default_azalia_audio_ops, + sizeof(default_azalia_audio_ops)); + memcpy(&phx_gfx_hda_audio_ops, &default_azalia_audio_ops, + sizeof(default_azalia_audio_ops)); + + SET_AUDIO_DEV_OPS(gfx_hda); + SET_AUDIO_DEV_OPS(hda); + + if (is_dev_enabled(psp)) { + psp->ops->acpi_name = crypto_acpi_name; + psp->ops->acpi_fill_ssdt = acpi_device_write_pci_dev; + } } struct chip_operations mainboard_ops = { - .init = mainboard_init, + .init = mainboard_init }; diff --git a/src/mainboard/msi/ms7e56/msi_id.S b/src/mainboard/msi/ms7e56/msi_id.S new file mode 100644 index 00000000000..9e78be477ef --- /dev/null +++ b/src/mainboard/msi/ms7e56/msi_id.S @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +.section .text, "a", @progbits + +/* The following structures must reside in the last 64KiB of flash */ + +.align 16 + +build_date: + .ascii "$MSESGN$" + .ascii "E7E56AMSI.2" + .byte 0x30 + DASHARO_MAJOR_VERSION + .byte 0x30 + DASHARO_MINOR_VERSION + .byte 0x30 + DASHARO_PATCH_VERSION + .byte ' ' + .asciz COREBOOT_DMI_DATE + +.align 8 + +msi_sign_on: + .ascii "$MS1E7E56AMSI2" + .byte 0x30 + DASHARO_MAJOR_VERSION + .byte 0x30 + DASHARO_MINOR_VERSION + .byte 0x30 + DASHARO_PATCH_VERSION + .byte 0x11 + .byte 0xe9 + .ascii "$MSVIDS$" + .byte 0x11 + +.align 8 + +bpa: + .ascii "$BPA" + .byte bpa_end - bpa + .byte 1 + .long 0x1000 + .long 6 + .byte 2 + .long 0x1be0000 + .long 0x20000 + .byte 3 + .long 0x1b90000 + .long 63 + .byte 4 + .byte 2 +bpa_end: + .zero 5 + + .asciz "@FC@" + .byte '2' + .byte 0 + .byte '1' + .byte 0 + .asciz "/P /fab /N /K" + .byte '2' + .byte 0 + .ascii "NULL" + .ascii "@@" + .zero 58 diff --git a/src/mainboard/msi/ms7e56/romhole.h b/src/mainboard/msi/ms7e56/romhole.h new file mode 100644 index 00000000000..bb58b2216ce --- /dev/null +++ b/src/mainboard/msi/ms7e56/romhole.h @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ROMHOLE_H_ +#define _ROMHOLE_H_ + +#define ROMHOLE_MAGIC 0x10012501 +#define NUM_PWD_ENTRIES 2 +#define PWD_SIZE 40 +#define NUM_GD_ENTRIES 8 +#define GD_SIZE 48 +#define NUM_US_ENTRIES 8 +#define US_SIZE 0x3851 +#define TYPE2_SIZE 256 +#define FTB_SIZE 105 +#define FIB_SIZE 512 +#define BUV_SIZE 2048 +#define NUM_VOLUMES 7 + +struct uuid_structure { + uint8_t magic0[4]; // always sSiD + uint16_t length; // structure length, always 0x1a + uint8_t magic1[3]; // awlays $uD + uint8_t space; // always 0x1 + uint8_t uuid[16]; // SMBIOS type 1 UUID +} __packed; + +struct pwd_entry { + uint8_t magic[3]; // always $s$ + uint8_t number; // ordinal number + uint8_t length; // length of pwd + uint8_t pwd[PWD_SIZE]; // password? +} __packed; + +struct pwd_structure { + uint8_t magic[4]; // always spWd + uint16_t length; // structure length + struct pwd_entry entries[NUM_PWD_ENTRIES]; +} __packed; + +struct gd_entry { + uint8_t magic[3]; // always $gD + uint8_t number; // ordinal number + uint16_t length; // length of gd + uint8_t gd[GD_SIZE]; // global data? +} __packed; + +struct gpdt_structure { + uint8_t magic[4]; // always gPdT + uint16_t length; // structure length + uint8_t num_entries; // number of entries + uint8_t space; // awlays zero + struct gd_entry entries[NUM_GD_ENTRIES]; +} __packed; + +struct us_entry { + uint8_t magic[3]; // always $uS + uint8_t number; // ordinal number + uint16_t length; // length of us + uint8_t us[US_SIZE]; // user data? +} __packed; + +struct ucsc_structure { + uint8_t magic[4]; // always uCsC + uint32_t length; // structure length + struct us_entry entries[NUM_US_ENTRIES]; +} __packed; + +struct type2_rw { + uint8_t magic0[4]; // always t2Rw + uint16_t length; // structure length + uint8_t magic1[3]; // always $tW + uint8_t space; // always 0x1 + uint8_t smbios_type2[TYPE2_SIZE]; // SMBIOS type2 table +} __packed; + +struct ftb_structure { + uint8_t magic0[4]; // always $FTB + uint16_t length; // structure length + uint8_t magic1[4]; // always $DIB + uint16_t space0; // always 0x2 + uint16_t size; // size of data field, always 105 + uint16_t space1; // always 0x0 + uint8_t magic2[4]; // always MFTD + uint8_t data[FTB_SIZE]; // default 0xfe +} __packed; + +struct fib_structure { + uint8_t magic0[4]; // always $FIB + uint16_t length; // structure length + uint16_t size; // size of data field, always 512 + uint8_t magic1[4]; // always $MFX + uint8_t data[FIB_SIZE]; // default 0xfa +} __packed; + +/* Structure present in newer releases of MSI PRO Z790-P A.40/1.40 */ +struct buv_structure { + uint8_t magic0[4]; // always $BuV + uint16_t length; // structure length + uint8_t magic1[3]; // always $Bv + uint8_t number; // always 0x1 + uint8_t data[BUV_SIZE]; // default 0xff +} __packed; + +struct volume_entry { + uint8_t number; // ordinal number in ascii + uint32_t address; // volume base address + uint32_t size; // volume size + uint8_t space; // always 0xff +} __packed; + +struct ris_structure { + uint8_t magic0[4]; // always $RiS + uint16_t length; // structure length + uint8_t magic1[4]; // always $RiT + /* Array below keep the addresses and sizes of UEFI Firmware Volumes */ + struct volume_entry volumes[NUM_VOLUMES]; +} __packed; + +/* Place the following struct in the ROMHOLE flash region with 64K/128K alignment */ +struct msi_romhole { + uint32_t magic0; // 0x10012501 + uint32_t length; // length of the structure + char magic1[4]; // always SYSD + uint32_t address; // romhole address in flash + uint32_t size; // romhole total size + uint8_t pad0[48]; // always 0xff + struct uuid_structure uuid; + struct pwd_structure pwd; + struct gpdt_structure gpdt; + struct ucsc_structure ucsc; + struct type2_rw t2rw; + struct ftb_structure ftb; + struct fib_structure fib; + struct buv_structure buv; + struct ris_structure ris; + // the rest is padded with 0xff by cbfstool +} __packed; + +#endif diff --git a/src/mainboard/msi/ms7e56/smbios.c b/src/mainboard/msi/ms7e56/smbios.c new file mode 100644 index 00000000000..b660373d526 --- /dev/null +++ b/src/mainboard/msi/ms7e56/smbios.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include "romhole.h" + +struct smbios_type2_v3_4 { + struct smbios_header header; + u8 manufacturer; + u8 product_name; + u8 version; + u8 serial_number; + u8 asset_tag; + u8 feature_flags; + u8 location_in_chassis; + u16 chassis_handle; + u8 board_type; + u8 contained_objects; + u8 eos[2]; +} __packed; + +static struct msi_romhole *romhole_addr = NULL; + +static struct msi_romhole *get_msi_romhole_address(void) +{ + struct region_device rdev; + + if (romhole_addr) + return romhole_addr; + + if (fmap_locate_area_as_rdev("ROMHOLE", &rdev)) + return NULL; + + romhole_addr = (struct msi_romhole *)rdev_mmap_full(&rdev); + + return romhole_addr; +} + +u8 smbios_mainboard_feature_flags(void) +{ + return SMBIOS_FEATURE_FLAGS_HOSTING_BOARD | SMBIOS_FEATURE_FLAGS_REPLACEABLE; +} + +smbios_wakeup_type smbios_system_wakeup_type(void) +{ + return SMBIOS_WAKEUP_TYPE_POWER_SWITCH; +} + +const char *smbios_system_product_name(void) +{ + return "MS-7E56"; +} + +const char *smbios_mainboard_product_name(void) +{ + return CONFIG_MAINBOARD_PART_NUMBER; +} + +/* Only baseboard serial number is populated */ +const char *smbios_system_serial_number(void) +{ + return "Default string"; +} + +const char *smbios_system_sku(void) +{ + return "Default string"; +} + +void smbios_system_set_uuid(u8 *uuid) +{ + if (!get_msi_romhole_address()) + return; + + memcpy(uuid, romhole_addr->uuid.uuid, 16); +} + +static const char* get_smbios_string(u8 *str_table_start, u8 string_index, + const char *fallback) +{ + u8 i; + char *smbios_str = (char *)str_table_start; + + for (i = 1; i < string_index; i++) { + if (strlen(smbios_str)) + smbios_str += strlen(smbios_str) + 1; + else + return fallback; + } + + return strlen(smbios_str) ? (const char *)smbios_str : fallback; +} + +const char *smbios_mainboard_serial_number(void) +{ + struct smbios_type2_v3_4 *type2; + + if (!get_msi_romhole_address()) + return CONFIG_MAINBOARD_SERIAL_NUMBER; + + type2 = (struct smbios_type2_v3_4 *)romhole_addr->t2rw.smbios_type2; + /* Do some sanity checks first */ + if (type2->header.type != 2 || + type2->header.length == 0 || + type2->header.length == 0xff || + smbios_string_table_len(type2->eos) == 0) + return CONFIG_MAINBOARD_SERIAL_NUMBER; + + return get_smbios_string(type2->eos, type2->serial_number, + CONFIG_MAINBOARD_SERIAL_NUMBER); +} + +const char *smbios_mainboard_version(void) +{ + struct smbios_type2_v3_4 *type2; + + if (!get_msi_romhole_address()) + return CONFIG_MAINBOARD_VERSION; + + type2 = (struct smbios_type2_v3_4 *)romhole_addr->t2rw.smbios_type2; + /* Do some sanity checks first */ + if (type2->header.type != 2 || + type2->header.length == 0 || + type2->header.length == 0xff || + smbios_string_table_len(type2->eos) == 0) + return CONFIG_MAINBOARD_VERSION; + + return get_smbios_string(type2->eos, type2->version, + CONFIG_MAINBOARD_VERSION); +} diff --git a/src/mainboard/msi/ms7e56/update_devicetree.c b/src/mainboard/msi/ms7e56/update_devicetree.c deleted file mode 100644 index 5938f2a735f..00000000000 --- a/src/mainboard/msi/ms7e56/update_devicetree.c +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include "update_devicetree.h" - -static void mainboard_update_mpio(void) -{ -} - -static void mainboard_update_ddi(void) -{ -} - -void mainboard_update_devicetree_opensil(void) -{ - mainboard_update_mpio(); - mainboard_update_ddi(); -} diff --git a/src/mainboard/msi/ms7e56/update_devicetree.h b/src/mainboard/msi/ms7e56/update_devicetree.h deleted file mode 100644 index 6f98dbd0ef4..00000000000 --- a/src/mainboard/msi/ms7e56/update_devicetree.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef MAINBOARD_UPDATE_DEVICETREE_H -#define MAINBOARD_UPDATE_DEVICETREE_H - -void mainboard_update_devicetree_opensil(void); - -#endif /* MAINBOARD_UPDATE_DEVICETREE_H */ diff --git a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld index 024afbe7e5f..bb37c9ae1eb 100644 --- a/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld +++ b/src/soc/amd/common/block/cpu/noncar/memlayout_x86.ld @@ -36,6 +36,10 @@ BOOTBLOCK_ADDR = BOOTBLOCK_END - CONFIG_C_ENV_BOOTBLOCK_SIZE; * | (VERSTAGE_SIZE) | * +--------------------------------+ VERSTAGE_ADDR * | | + * | Promontory FW (if reqd) | + * | (256K) | + * +--------------------------------+ PROMONTORY_FW_ADDR + * | | * | FSP-M | * | (FSP_M_SIZE) | * +--------------------------------+ FSP_M_ADDR @@ -102,6 +106,10 @@ SECTIONS REGION(fspm, CONFIG_FSP_M_ADDR, CONFIG_FSP_M_SIZE, 1) #endif +#if CONFIG_PROMONTORY_FW_ADDR > 0 + REGION(promontory, CONFIG_PROMONTORY_FW_ADDR, 256K, 4K) +#endif + #if CONFIG(VBOOT_SEPARATE_VERSTAGE) && !CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) VERSTAGE(CONFIG_VERSTAGE_ADDR, CONFIG_VERSTAGE_SIZE) #endif diff --git a/src/soc/amd/common/block/graphics/graphics.c b/src/soc/amd/common/block/graphics/graphics.c index 369fd85192e..648286d68d9 100644 --- a/src/soc/amd/common/block/graphics/graphics.c +++ b/src/soc/amd/common/block/graphics/graphics.c @@ -131,7 +131,7 @@ static void graphics_fill_ssdt(const struct device *dev) acpi_device_write_pci_dev(dev); /* Use the VFCT copy when using GOP */ - if (!CONFIG(RUN_FSP_GOP)) + if (!CONFIG(RUN_FSP_GOP) && !CONFIG(SOC_AMD_OPENSIL)) pci_rom_ssdt(dev); if (CONFIG(SOC_AMD_COMMON_BLOCK_GRAPHICS_ATIF)) diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index 5781dea3af8..8b793dd1cc6 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -124,6 +124,8 @@ struct espi_config { /* Use ESPI_VW_IRQ_* above */ uint32_t vw_irq_polarity; + + uint32_t irq_mask; }; /* diff --git a/src/soc/amd/common/block/include/amdblocks/psp_efs.h b/src/soc/amd/common/block/include/amdblocks/psp_efs.h index 9f1c1e8cbd5..fe05d9c4d5f 100644 --- a/src/soc/amd/common/block/include/amdblocks/psp_efs.h +++ b/src/soc/amd/common/block/include/amdblocks/psp_efs.h @@ -47,7 +47,7 @@ struct embedded_firmware { uint32_t reserved_2Ch; uint32_t promontory_fw_ptr; uint32_t lp_promontory_fw_ptr; - uint32_t reserved_38h; + uint32_t promontory19_fw_ptr; uint32_t reserved_3Ch; uint8_t spi_readmode_f15_mod_60_6f; uint8_t fast_speed_new_f15_mod_60_6f; @@ -65,5 +65,6 @@ struct embedded_firmware { } __packed __aligned(16); bool read_efs_spi_settings(uint8_t *mode, uint8_t *speed); +size_t efs_read_promontory_fw(void *buf); #endif /* AMD_COMMON_PSP_EFS_H */ diff --git a/src/soc/amd/common/block/lpc/espi_def.h b/src/soc/amd/common/block/lpc/espi_def.h index 7f371c1a1a5..1b4fcb36f5d 100644 --- a/src/soc/amd/common/block/lpc/espi_def.h +++ b/src/soc/amd/common/block/lpc/espi_def.h @@ -25,6 +25,7 @@ #define ESPI_WDG_EN (1 << 0) #define ESPI_GLOBAL_CONTROL_1 0x34 +#define ESPI_REQ_NOTWITH_VW_REQ (1 << 21) #define ESPI_ALERT_ENABLE (1 << 20) /* Mendocino and later SoCs */ #define ESPI_RGCMD_INT_MAP_SHIFT 13 #define ESPI_RGCMD_INT_MAP_MASK (0x1f << ESPI_RGCMD_INT_MAP_SHIFT) @@ -80,6 +81,8 @@ #define ESPI_MMIO_BASE_REG4 0xbc #define ESPI_MMIO_SIZE_REG2 0xc0 +#define ESPI_RXVW_INDEX 0xa4 +#define ESPI_RXVW_MISC_CNTL 0xa8 #define ESPI_RXVW_POLARITY 0xac #define ESPI_DECODE_RANGES_PER_REG_GROUP 4 diff --git a/src/soc/amd/common/block/lpc/espi_util.c b/src/soc/amd/common/block/lpc/espi_util.c index f05575ab748..fd540c60877 100644 --- a/src/soc/amd/common/block/lpc/espi_util.c +++ b/src/soc/amd/common/block/lpc/espi_util.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -1103,6 +1104,9 @@ enum cb_err espi_setup(void) espi_write32(ESPI_GLOBAL_CONTROL_1, ctrl); + if (cfg->irq_mask) + pm_write32(PM_ESPI_INTR_CTRL, cfg->irq_mask); + printk(BIOS_SPEW, "Finished initializing ESPI.\n"); return CB_SUCCESS; diff --git a/src/soc/amd/common/block/pci/pcie_gpp.c b/src/soc/amd/common/block/pci/pcie_gpp.c index 0f983d04bea..9dac1c9d7e3 100644 --- a/src/soc/amd/common/block/pci/pcie_gpp.c +++ b/src/soc/amd/common/block/pci/pcie_gpp.c @@ -71,6 +71,16 @@ struct device_operations amd_internal_pcie_gpp_ops = { .acpi_fill_ssdt = acpi_device_write_gpp_pci_dev, }; +struct device_operations amd_internal_pcie_gpp_ops_exp = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .acpi_name = pcie_gpp_acpi_name, + .acpi_fill_ssdt = acpi_device_write_gpp_pci_dev, +}; + struct device_operations amd_external_pcie_gpp_ops = { .read_resources = pci_bus_read_resources, .set_resources = pci_dev_set_resources, diff --git a/src/soc/amd/common/block/psp/Makefile.mk b/src/soc/amd/common/block/psp/Makefile.mk index 9e12743190a..c8dbb0965ab 100644 --- a/src/soc/amd/common/block/psp/Makefile.mk +++ b/src/soc/amd/common/block/psp/Makefile.mk @@ -10,6 +10,7 @@ smm-y += psp_smm.c bootblock-y += psp_efs.c verstage-y += psp_efs.c +ramstage-y += psp_efs.c all-y += ftpm.c diff --git a/src/soc/amd/common/block/psp/psp_efs.c b/src/soc/amd/common/block/psp/psp_efs.c index fa69aea5548..a22c17dcadf 100644 --- a/src/soc/amd/common/block/psp/psp_efs.c +++ b/src/soc/amd/common/block/psp/psp_efs.c @@ -3,9 +3,13 @@ #include #include #include +#include #include +#include #include +#define PSP_FW_FILE_HEADER_SIZE 256 + bool read_efs_spi_settings(uint8_t *mode, uint8_t *speed) { bool ret = false; @@ -28,3 +32,62 @@ bool read_efs_spi_settings(uint8_t *mode, uint8_t *speed) rdev_munmap(boot_device_ro(), efs); return ret; } + +size_t efs_read_promontory_fw(void *buf) +{ + struct embedded_firmware *efs; + const struct region_device *boot_dev = boot_device_ro(); + uint8_t file_header[PSP_FW_FILE_HEADER_SIZE + 8]; + size_t read_bytes, fw_size; + uint32_t offset; + + if (!boot_dev || !buf) + return 0; + + efs = rdev_mmap(boot_dev, EFS_OFFSET, sizeof(*efs)); + if (!efs) + return 0; + + if (efs->signature != EMBEDDED_FW_SIGNATURE) { + rdev_munmap(boot_dev, efs); + return 0; + } + + offset = efs->promontory_fw_ptr; + rdev_munmap(boot_dev, efs); + + read_bytes = rdev_readat(boot_dev, file_header, offset, sizeof(file_header)); + if (read_bytes != sizeof(file_header)) + return 0; + + /* Get Promontory FW size */ + if (strncmp((char *)&file_header[0x10], "$PS1", 4)) { + /* Check Promontory FW signature */ + if (!strncmp((char *)file_header, "_PT_", 4)) + fw_size = *(uint32_t *)&file_header[4]; + else + return 0; + } else { + /* Check Promontory FW signature */ + if (!strncmp((char *)&file_header[PSP_FW_FILE_HEADER_SIZE], "_PT_", 4)) + fw_size = *(uint32_t *)&file_header[PSP_FW_FILE_HEADER_SIZE + 4]; + else + return 0; + + offset += PSP_FW_FILE_HEADER_SIZE; + } + + if (fw_size > 256 * KiB) { + printk(BIOS_DEBUG, "Found Promontory FW too big (size: %lx)\n", fw_size); + return 0; + } + + printk(BIOS_DEBUG, "Found Promontory FW @ 0x%08x (size: %lx)\n", + offset, fw_size); + + read_bytes = rdev_readat(boot_dev, buf, offset, fw_size); + if (read_bytes != fw_size) + return 0; + + return fw_size; +} diff --git a/src/soc/amd/phoenix/Kconfig b/src/soc/amd/phoenix/Kconfig index 6f82513e3be..1d1e215106b 100644 --- a/src/soc/amd/phoenix/Kconfig +++ b/src/soc/amd/phoenix/Kconfig @@ -27,7 +27,7 @@ config SOC_AMD_PHOENIX_BASE select SOC_AMD_COMMON_BLOCK_ACPI # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_ACPIMMIO # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_ACPI_ALIB # TODO: Check if this is still correct - select SOC_AMD_COMMON_BLOCK_ACPI_CPPC if !SOC_AMD_PHOENIX_OPENSIL # TODO: add support for openSIL case + select SOC_AMD_COMMON_BLOCK_ACPI_CPPC select SOC_AMD_COMMON_BLOCK_ACPI_CPU_POWER_STATE select SOC_AMD_COMMON_BLOCK_ACPI_GPIO # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_ACPI_IVRS # TODO: Check if this is still correct @@ -116,6 +116,7 @@ config SOC_AMD_PHOENIX_OPENSIL select SOC_AMD_PHOENIX_BASE select SOC_AMD_OPENSIL select SOC_AMD_OPENSIL_PHOENIX_POC + select SOC_AMD_COMMON_BLOCK_APOB_MEMCTX_CMOS select UDK_2017_BINDING help AMD Phoenix support using OpenSIL (Proof of Comcept) @@ -228,6 +229,15 @@ config VERSTAGE_ADDR Sets the address in DRAM where verstage should be loaded if running as a separate stage on x86. +config PROMONTORY_FW_ADDR + hex + default 0x21A0000 if SOC_AMD_PHOENIX_AM5 + default 0x0 + help + Sets the address in DRAM where Promontory FW should be loaded on AM5. + Promontory needs ~160KB of space. We allocate 256KB between romstage + and verstage, so that it will be placed in early reserved DRAM. + config VERSTAGE_SIZE hex depends on VBOOT_SEPARATE_VERSTAGE diff --git a/src/soc/amd/phoenix/acpi.c b/src/soc/amd/phoenix/acpi.c index 90738bf1608..08b3a4bd96a 100644 --- a/src/soc/amd/phoenix/acpi.c +++ b/src/soc/amd/phoenix/acpi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,10 @@ #include #include "chip.h" +#if CONFIG(SOC_AMD_PHOENIX_OPENSIL) +#include +#endif + unsigned long soc_acpi_fill_ivrs40(unsigned long current, acpi_ivrs_ivhd40_t *ivhd, struct device *nb_dev, struct device *iommu_dev) { @@ -118,7 +123,7 @@ static void send_ivrs_to_psp(struct acpi_rsdp *rsdp) buffer.info.ivrs_table_buffer = (uint64_t)hdr; buffer.info.ivrs_table_size = hdr->length; - printk(BIOS_DEBUG, "PSP: Sending IVRS ACPI table\n"); + printk(BIOS_DEBUG, "PSP: Sending IVRS ACPI table "); cmd_status = send_psp_command(MBOX_BIOS_CMD_SEND_IVRS_ACPI_TABLE, &buffer); @@ -165,3 +170,37 @@ const acpi_cstate_t *get_cstate_config_data(size_t *size) *size = ARRAY_SIZE(cstate_cfg_table); return cstate_cfg_table; } + +#if CONFIG(SOC_AMD_PHOENIX_OPENSIL) +enum cb_err get_ccx_cppc_min_frequency(uint32_t *freq) +{ + SIL_CONTEXT SilContext = { + .ApobBaseAddress = CONFIG_PSP_APOB_DRAM_ADDRESS, + .SilMemBaseAddress = (uintptr_t)cbmem_find(CBMEM_ID_AMD_OPENSIL) + }; + + if (SilContext.SilMemBaseAddress == 0) + return CB_ERR; + + if (xPrfGetCppcMinFrequency(&SilContext, freq) != SilPass) + return CB_ERR; + + return CB_SUCCESS; +} + +enum cb_err get_ccx_cppc_nom_frequency(uint32_t *freq) +{ + SIL_CONTEXT SilContext = { + .ApobBaseAddress = CONFIG_PSP_APOB_DRAM_ADDRESS, + .SilMemBaseAddress = (uintptr_t)cbmem_find(CBMEM_ID_AMD_OPENSIL) + }; + + if (SilContext.SilMemBaseAddress == 0) + return CB_ERR; + + if (xPrfGetCppcNomFrequency(&SilContext, freq) != SilPass) + return CB_ERR; + + return CB_SUCCESS; +} +#endif diff --git a/src/soc/amd/phoenix/acpi/ioapic_routing.asl b/src/soc/amd/phoenix/acpi/ioapic_routing.asl new file mode 100644 index 00000000000..aec8b39b2ed --- /dev/null +++ b/src/soc/amd/phoenix/acpi/ioapic_routing.asl @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Scope (PCI0) { + OperationRegion (NAPC, PCI_Config, 0xB8, 0x08) + Field (NAPC, DWordAcc, NoLock, Preserve) + { + NAPX, 32, + NAPD, 32 + } +} + +/* + * Clears IoapicSbFeatureEn on GNB IOAPIC to switch routing to IOAPIC. + */ +Mutex (NAPM, 0x00) +Method (NAPE, 0, NotSerialized) +{ + If (PICM == 0) + { + Return + } + + \_SB.DSPI() + + Acquire (NAPM, 0xFFFF) + \_SB.PCI0.NAPX = 0x14300000 + Local0 = \_SB.PCI0.NAPD + Local0 &= 0xFFFFFFEF + \_SB.PCI0.NAPD = Local0 + Release (NAPM) +} diff --git a/src/soc/amd/phoenix/acpi/pci_int_defs.asl b/src/soc/amd/phoenix/acpi/pci_int_defs.asl index 5d6aadc3219..1cb325822d0 100644 --- a/src/soc/amd/phoenix/acpi/pci_int_defs.asl +++ b/src/soc/amd/phoenix/acpi/pci_int_defs.asl @@ -22,6 +22,27 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { PIRG, 0x00000008, /* Index 6: INTG */ PIRH, 0x00000008, /* Index 7: INTH */ + Offset (0x0C), + SIRA, 0x00000008, /* Index 0x0C: Serial IRQA */ + SIRB, 0x00000008, /* Index 0x0D: Serial IRQB */ + SIRC, 0x00000008, /* Index 0x0E: Serial IRQC */ + SIRD, 0x00000008, /* Index 0x0F: Serial IRQD */ + PIRS, 0x00000008, /* Index 0x10: SCI */ + Offset (0x13), + HDAD, 0x00000008, /* Index 0x13: HDA */ + Offset (0x17), + SDCL, 0x00000008, /* Index 0x17: SD */ + Offset (0x1A), + SDIO, 0x00000008, /* Index 0x1A: SDIO */ + Offset (0x30), + USB1, 0x00000008, /* Index 0x30: XHCI1 */ + Offset (0x34), + USB3, 0x00000008, /* Index 0x34: XHCI3 */ + Offset (0x41), + SATA, 0x00000008, /* Index 0x41: SATA */ + Offset (0x43), + EMMC, 0x00000008, /* Index 0x43: EMMC */ + Offset (0x60), PGSC, 0x00000008, /* Index 0x60: GEventSci */ PGSM, 0x00000008, /* Index 0x61: GEventSmi */ @@ -69,3 +90,27 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { IUA2, 0x00000008, /* Index 0xF8: UART2 */ IUA3, 0x00000008, /* Index 0xF9: UART3 */ } + +Method (DSPI, 0, NotSerialized) +{ + PIRA = 0x1F + HDAD = 0x1F + PIRB = 0x1F + PIRC = 0x1F + USB1 = 0x1F + USB3 = 0x1F + PIRD = 0x1F + SATA = 0x1F + PIRE = 0x1F + PIRF = 0x1F + PIRG = 0x1F + PIRH = 0x1F + IORA = 0x10 + IORB = 0x11 + IORC = 0x12 + IORD = 0x13 + IORE = 0x14 + IORF = 0x15 + IORG = 0x16 + IORH = 0x17 +} diff --git a/src/soc/amd/phoenix/acpi/soc.asl b/src/soc/amd/phoenix/acpi/soc.asl index ee2e9c886b0..41bdbdc1c01 100644 --- a/src/soc/amd/phoenix/acpi/soc.asl +++ b/src/soc/amd/phoenix/acpi/soc.asl @@ -24,6 +24,8 @@ Scope(\_SB) { Scope(PCI0) { #include } /* End PCI0 scope */ + + #include "ioapic_routing.asl" } /* End \_SB scope */ #include diff --git a/src/soc/amd/phoenix/chipset_opensil.cb b/src/soc/amd/phoenix/chipset_opensil.cb index 0a88128c480..f3a3cc8f872 100644 --- a/src/soc/amd/phoenix/chipset_opensil.cb +++ b/src/soc/amd/phoenix/chipset_opensil.cb @@ -64,9 +64,9 @@ chip soc/amd/phoenix device pci 08.0 on end # Dummy device function, do not disable device pci 08.1 alias gpp_bridge_a on # Internal GPP Bridge 0 to Bus A - ops amd_internal_pcie_gpp_ops + ops amd_internal_pcie_gpp_ops_exp device pci 0.0 alias gfx off ops amd_graphics_ops end # Internal GPU (GFX) - device pci 0.1 alias gfx_hda off end # Display HD Audio Controller (GFXAZ) + device pci 0.1 alias gfx_hda off ops default_azalia_audio_ops end # Display HD Audio Controller (GFXAZ) device pci 0.2 alias crypto off end # Crypto Coprocessor device pci 0.3 alias xhci_0 off ops xhci_pci_ops @@ -116,13 +116,13 @@ chip soc/amd/phoenix device pci 0.7 alias mp2 off end # Sensor Fusion Hub (MP2) end device pci 08.2 alias gpp_bridge_b on # Internal GPP Bridge 1 to Bus B - ops amd_internal_pcie_gpp_ops + ops amd_internal_pcie_gpp_ops_exp device pci 0.0 on end # dummy, do not disable device pci 0.1 alias ipu off end end device pci 08.3 alias gpp_bridge_c on # Internal GPP Bridge 2 to Bus C - ops amd_internal_pcie_gpp_ops + ops amd_internal_pcie_gpp_ops_exp device pci 0.0 on end # dummy, do not disable device pci 0.3 alias usb4_xhci_0 off ops xhci_pci_ops diff --git a/src/soc/amd/phoenix/fch.c b/src/soc/amd/phoenix/fch.c index df1dd8850d1..f3b717f664a 100644 --- a/src/soc/amd/phoenix/fch.c +++ b/src/soc/amd/phoenix/fch.c @@ -105,6 +105,7 @@ static void fch_init_acpi_ports(void) response of the I/O write. */ reg = pm_read32(PM_PCI_CTRL); reg |= FORCE_SLPSTATE_RETRY; + reg &= ~FORCE_STPCLK_RETRY; pm_write32(PM_PCI_CTRL, reg); /* Disable SlpTyp feature */ diff --git a/src/soc/amd/phoenix/include/soc/amd_pci_int_defs.h b/src/soc/amd/phoenix/include/soc/amd_pci_int_defs.h index 74bb4548c48..8adf01d2280 100644 --- a/src/soc/amd/phoenix/include/soc/amd_pci_int_defs.h +++ b/src/soc/amd/phoenix/include/soc/amd_pci_int_defs.h @@ -32,14 +32,17 @@ #define PIRQ_ASF 0x12 /* ASF */ /* 0x13-0x15 reserved */ #define PIRQ_PMON 0x16 /* Performance Monitor */ -/* 0x17-0x19 reserved */ +#define PIRQ_SD 0x17 /* Performance Monitor */ +/* 0x18-0x19 reserved */ #define PIRQ_SDIO 0x1a /* SDIO */ /* 0x1b-0x1f reserved */ #define PIRQ_CIR 0x20 /* CIR, no IRQ connected */ #define PIRQ_GPIOA 0x21 /* GPIOa from PAD_FANIN0 */ #define PIRQ_GPIOB 0x22 /* GPIOb from PAD_FANOUT0 */ #define PIRQ_GPIOC 0x23 /* GPIOc no IRQ connected */ -/* 0x24-0x5f reserved */ +/* 0x24-0x42 reserved */ +#define PIRQ_EMMC 0x43 /* eMMC */ +/* 0x44-0x5f reserved */ #define PIRQ_GSCI 0x60 /* GEventSci Interrupt */ #define PIRQ_GSMI 0x61 /* GEventSmi Interrupt */ #define PIRQ_GPIO 0x62 /* GPIO Controller Interrupt */ diff --git a/src/soc/amd/phoenix/include/soc/southbridge.h b/src/soc/amd/phoenix/include/soc/southbridge.h index 60ac3951f9d..8663907aef1 100644 --- a/src/soc/amd/phoenix/include/soc/southbridge.h +++ b/src/soc/amd/phoenix/include/soc/southbridge.h @@ -9,6 +9,7 @@ #define PM_ISACONTROL 0x04 #define ABCLKGATEEN BIT(16) #define PM_PCI_CTRL 0x08 +#define FORCE_STPCLK_RETRY BIT(24) #define FORCE_SLPSTATE_RETRY BIT(25) #define PWR_RESET_CFG 0x10 #define TOGGLE_ALL_PWR_GOOD BIT(1) diff --git a/src/soc/amd/phoenix/root_complex.c b/src/soc/amd/phoenix/root_complex.c index 724121c1aaa..7fc8a374660 100644 --- a/src/soc/amd/phoenix/root_complex.c +++ b/src/soc/amd/phoenix/root_complex.c @@ -2,8 +2,12 @@ /* TODO: Update for Phoenix */ +#include #include +#include +#include #include +#include #include #include #include @@ -85,10 +89,104 @@ static void acipgen_dptci(void) sizeof(no_battery_input)); } +struct pci_dev_int_routes { + unsigned int devfn; + unsigned int num_irqs; + unsigned int irq_base; +}; + +static const struct pci_dev_int_routes iohc_devs[] = { + { .devfn = PCI_DEVFN(0x14, 0), .num_irqs = 4, .irq_base = 16 }, + { .devfn = PCI_DEVFN(0x08, 0), .num_irqs = 1, .irq_base = 28 }, +}; + +static void acpigen_write_PRT_GSI(const struct device *rb) +{ + char *pkg_count; + const struct device *dev; + + pkg_count = acpigen_write_package(0); /* Package - APIC Routing */ + + for (unsigned int d = 0; d < ARRAY_SIZE(iohc_devs); d++) { + dev = pcidev_path_behind(rb->upstream, iohc_devs[d].devfn); + if (!dev || !dev->enabled) + continue; + + for (unsigned int i = 0; i < iohc_devs[d].num_irqs; ++i) { + (*pkg_count)++; + acpigen_write_PRT_GSI_entry( + PCI_SLOT(iohc_devs[d].devfn), + i, /* pin */ + iohc_devs[d].irq_base + i); + } + } + + acpigen_pop_len(); /* Package - APIC Routing */ +} + +static void acpigen_write_PRT_PIC(const struct device *rb) +{ + char link_template[] = "\\_SB.INTX"; + char *pkg_count; + const struct device *dev; + + pkg_count = acpigen_write_package(0); /* Package - PIC Routing */ + for (unsigned int d = 0; d < ARRAY_SIZE(iohc_devs); d++) { + dev = pcidev_path_behind(rb->upstream, iohc_devs[d].devfn); + if (!dev || !dev->enabled) + continue; + + for (unsigned int i = 0; i < iohc_devs[d].num_irqs; i++) { + link_template[8] = 'A' + ((iohc_devs[d].irq_base + i) % 8); + (*pkg_count)++; + acpigen_write_PRT_source_entry( + PCI_SLOT(iohc_devs[d].devfn), + i, /* pin */ + link_template /* Source */, + 0 /* Source Index */); + } + } + + acpigen_pop_len(); /* Package - PIC Routing */ +} + +static void acpigen_write_host_bridge_PRT(const struct device *dev) +{ + acpigen_write_method("_PRT", 0); + + /* If (PICM) */ + acpigen_write_if(); + acpigen_emit_namestring("PICM"); + + /* Return (Package{...}) */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_PRT_GSI(dev); + + /* Else */ + acpigen_write_else(); + + /* Return (Package{...}) */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_PRT_PIC(dev); + + acpigen_pop_len(); /* End Else */ + + acpigen_pop_len(); /* Method */ +} + static void root_complex_fill_ssdt(const struct device *device) { + const char *acpi_scope = acpi_device_path(dev_get_domain(device)); + if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC)) acipgen_dptci(); + + acpigen_write_scope(acpi_scope); + + printk(BIOS_DEBUG, "%s: writing _PRT\n", acpi_scope); + acpigen_write_host_bridge_PRT(device); + + acpigen_pop_len(); /* Scope */ } static const char *gnb_acpi_name(const struct device *dev) diff --git a/src/vendorcode/amd/opensil/Kconfig.debug b/src/vendorcode/amd/opensil/Kconfig.debug index 3066844e56f..c57574c20b3 100644 --- a/src/vendorcode/amd/opensil/Kconfig.debug +++ b/src/vendorcode/amd/opensil/Kconfig.debug @@ -96,6 +96,12 @@ config OPENSIL_DEBUG_GFX help Enable printing graphics related messages. +config OPENSIL_DEBUG_PROM + bool "Enable Promontory messages" + default y + help + Enable printing Promontory related messages. + config OPENSIL_DEBUG_XUSL_CMN bool "Enable xUSL CommonLib messages" default y diff --git a/src/vendorcode/amd/opensil/phoenix_poc/Makefile.mk b/src/vendorcode/amd/opensil/phoenix_poc/Makefile.mk index 5d36d56f934..fc97ac90238 100644 --- a/src/vendorcode/amd/opensil/phoenix_poc/Makefile.mk +++ b/src/vendorcode/amd/opensil/phoenix_poc/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only subdirs-y += mpio +subdirs-$(CONFIG_DRIVERS_AMD_PROMONTORY21) += prom21 CPPFLAGS_common += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF diff --git a/src/vendorcode/amd/opensil/phoenix_poc/filter.h b/src/vendorcode/amd/opensil/phoenix_poc/filter.h index 9852a7c2642..533884e8add 100644 --- a/src/vendorcode/amd/opensil/phoenix_poc/filter.h +++ b/src/vendorcode/amd/opensil/phoenix_poc/filter.h @@ -13,6 +13,7 @@ #define DEBUG_FILTER_CXL 0x00000200UL #define DEBUG_FILTER_RCMGR 0x00000800UL #define DEBUG_FILTER_GFX 0x00001000UL +#define DEBUG_FILTER_PROM 0x00002000UL #define SIL_DEBUG(topic) (CONFIG(OPENSIL_DEBUG_##topic) ? DEBUG_FILTER_##topic : 0) @@ -28,4 +29,5 @@ SIL_DEBUG(RAS) | \ SIL_DEBUG(CXL) | \ SIL_DEBUG(RCMGR) | \ - SIL_DEBUG(GFX)) + SIL_DEBUG(GFX) | \ + SIL_DEBUG(PROM)) diff --git a/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.c b/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.c index ee678539400..4f0b391e12a 100644 --- a/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.c +++ b/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.c @@ -3,18 +3,58 @@ #include #include #include +#include +#include #include +#include #include #include +#include #include #include #include #include "chip.h" +#include "../prom21/prom21.h" + +MPIO_DDI_DESCRIPTOR ddi_descriptor_list[MAX_DDI_PORTS]; static void mpio_params_config(SIL_CONTEXT *SilContext) { MPIOCLASS_COMMON_INPUT_BLK *mpio_data = SilFindStructure(SilContext, SilId_MpioClass, 0); + MPIOCLASS_PHX_INPUT_BLK *phx_data = SilFindStructure(SilContext, SilId_MpioClass, 1); + struct device *gnb = DEV_PTR(gnb); + struct device *iommu = DEV_PTR(iommu); + struct device *psp = DEV_PTR(crypto); + struct device *nbif = pcidev_on_root(8, 0); + struct device *acp = DEV_PTR(acp); + struct device *hda = DEV_PTR(hda); + struct device *mp2 = DEV_PTR(mp2); + struct device *gfx = DEV_PTR(gfx); + struct device *gfx_hda = DEV_PTR(gfx_hda); + struct device *nbifrc = DEV_PTR(gpp_bridge_a); + + phx_data->AcpController = is_dev_enabled(acp); + phx_data->CfgHdAudioEnable = is_dev_enabled(hda); + phx_data->CfgSensorHubEnable = is_dev_enabled(mp2); + + if (pcidev_get_ssid(acp)) + phx_data->CfgAcpSsid = pcidev_get_ssid(acp); + if (pcidev_get_ssid(gfx)) + phx_data->AmdCfgGnbIGPUSSID = pcidev_get_ssid(gfx); + if (pcidev_get_ssid(gfx_hda)) + phx_data->AmdCfgGnbIGPUAudioSSID = pcidev_get_ssid(gfx_hda); + if (pcidev_get_ssid(nbifrc)) + phx_data->CfgNbifRCSsid = pcidev_get_ssid(nbifrc); + if (pcidev_get_ssid(gnb)) + mpio_data->CfgNbioSsid = pcidev_get_ssid(gnb); + if (pcidev_get_ssid(iommu)) + mpio_data->CfgIommuSsid = pcidev_get_ssid(iommu); + if (pcidev_get_ssid(psp)) + mpio_data->CfgPspccpSsid = pcidev_get_ssid(psp); + if (pcidev_get_ssid(nbif)) + mpio_data->CfgNbifF0Ssid = pcidev_get_ssid(nbif); + mpio_data->CfgDxioClockGating = 1; mpio_data->PcieDxioTimingControlEnable = 0; mpio_data->PCIELinkReceiverDetectionPolling = 0; @@ -50,14 +90,8 @@ static void mpio_params_config(SIL_CONTEXT *SilContext) mpio_data->CfgPcieAriSupport = 1; mpio_data->CfgNbioCTOtoSC = 0; mpio_data->CfgNbioCTOIgnoreError = 1; - mpio_data->CfgNbioSsid = 0; - mpio_data->CfgIommuSsid = 0; - mpio_data->CfgPspccpSsid = 0; mpio_data->CfgNtbccpSsid = 0; - mpio_data->CfgNbifF0Ssid = 0; mpio_data->CfgNtbSsid = 0; - mpio_data->AmdPcieSubsystemDeviceID = 0x1453; - mpio_data->AmdPcieSubsystemVendorID = 0x1022; mpio_data->GppAtomicOps = 1; mpio_data->GfxAtomicOps = 1; mpio_data->AmdNbioReportEdbErrors = 0; @@ -86,6 +120,8 @@ static void mpio_params_config(SIL_CONTEXT *SilContext) /* TODO handle this differently on multisocket */ mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST; mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList; + ddi_descriptor_list[0].Flags = DESCRIPTOR_TERMINATE_LIST; + mpio_data->PcieTopologyData.PlatformData[0].DdiLinkList = ddi_descriptor_list; } WEAK_DEV_PTR(usb4_router_0); @@ -96,44 +132,73 @@ WEAK_DEV_PTR(usb4_pcie_bridge_1); static void nbio_params_config(SIL_CONTEXT *SilContext) { NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilContext, SilId_NbioClass, 0); + GFXCLASS_INPUT_BLK *gfx_data = SilFindStructure(SilContext, SilId_GfxClass, 0); NBIO_CONFIG_DATA *input = &nbio_data->NbioConfigData; + input->IoApicMMIOAddressReservedEnable = false; + input->CfgGnbIoapicAddress = GNB_IO_APIC_ADDR; + if (CONFIG(IOAPIC_PREDEFINED_ID)) { + input->IoApicIdPreDefineEn = 1; + input->IoApicIdBase = 33; + } input->EsmEnableAllRootPorts = false; input->EsmTargetSpeed = 16; input->CfgRxMarginPersistenceMode = 1; input->SevSnpSupport = false; + input->IommuAvicSupport = true; + input->IommuSupport = is_dev_enabled(DEV_PTR(iommu)); + input->CfgAzaliaEnable = is_dev_enabled(DEV_PTR(gfx_hda)); input->Usb4Rt0En = is_dev_enabled(DEV_PTR(usb4_router_0)); input->Usb4Rt0PcieTnlEn = is_dev_enabled(DEV_PTR(usb4_pcie_bridge_0)); input->Usb4Rt1En = is_dev_enabled(DEV_PTR(usb4_router_1)); input->Usb4Rt1PcieTnlEn = is_dev_enabled(DEV_PTR(usb4_pcie_bridge_1)); + gfx_data->Usb4Rt0En = input->Usb4Rt0En; + gfx_data->Usb4Rt1En = input->Usb4Rt1En; + + if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND)) + input->AmdApicMode = xApicMode; + else if (CONFIG(X2APIC_ONLY)) + input->AmdApicMode = x2ApicMode; + else + input->AmdApicMode = ApicAutoMode; } #ifndef MPIO_ENGINE_DATA_INITIALIZER -#define MPIO_ENGINE_DATA_INITIALIZER(mType, mStartLane, mEndLane, mHotplug, mGpioGroupId) \ - { .EngineType = mType, \ - .HotPluggable = mHotplug, \ - .StartLane = mStartLane, \ - .EndLane = mEndLane, \ - .GpioGroupId = mGpioGroupId, \ - } +#define MPIO_ENGINE_DATA_INITIALIZER(mType, mStartLane, mEndLane, mHotplug, mGpioGroupId) \ + { \ + .EngineType = mType, \ + .HotPluggable = mHotplug, \ + .StartLane = mStartLane, \ + .EndLane = mEndLane, \ + .GpioGroupId = mGpioGroupId, \ + } #endif #ifndef MPIO_PORT_DATA_INITIALIZER_PCIE -#define MPIO_PORT_DATA_INITIALIZER_PCIE(mPortPresent, mDevAddress, mDevFunction, mHotplug, mMaxLinkSpeed, \ - mMaxLinkCap, mAspm, mAspmL1_1, mAspmL1_2, mClkPmSupport) \ - { \ - .PortPresent = mPortPresent, \ - .DeviceNumber = mDevAddress, \ - .FunctionNumber = mDevFunction, \ - .LinkSpeedCapability = mMaxLinkSpeed, \ - .LinkAspm = mAspm, \ - .LinkAspmL1_1 = mAspmL1_1, \ - .LinkAspmL1_2 = mAspmL1_2, \ - .LinkHotplug = mHotplug, \ - .MiscControls = { \ - .LinkSafeMode = mMaxLinkCap, \ - .ClkPmSupport = mClkPmSupport, \ - .TurnOffUnusedLanes = 1, \ - }, \ - } +#define MPIO_PORT_DATA_INITIALIZER_PCIE(mPortPresent, mDevAddress, mDevFunction, mHotplug, \ + mMaxLinkSpeed, mMaxLinkCap, mAspm, mAspmL1_1, \ + mAspmL1_2, mClkPmSupport) \ + { \ + .PortPresent = mPortPresent, \ + .DeviceNumber = mDevAddress, \ + .FunctionNumber = mDevFunction, \ + .LinkSpeedCapability = mMaxLinkSpeed, \ + .LinkAspm = mAspm, \ + .LinkAspmL1_1 = mAspmL1_1, \ + .LinkAspmL1_2 = mAspmL1_2, \ + .LinkHotplug = mHotplug, \ + .MiscControls = { \ + .LinkSafeMode = mMaxLinkCap, \ + .ClkPmSupport = mClkPmSupport, \ + .TurnOffUnusedLanes = 1, \ + }, \ + } +#endif +#ifndef MPIO_DDI_DATA_INITIALIZER +#define MPIO_DDI_DATA_INITIALIZER(mConnectorType, mAuxIndex, mHdpIndex) \ + { \ + .ConnectorType = mConnectorType, \ + .AuxIndex = mAuxIndex, \ + .HdpIndex = mHdpIndex, \ + } #endif void opensil_mpio_per_device_config(struct device *dev) @@ -153,12 +218,15 @@ void opensil_mpio_per_device_config(struct device *dev) } } - static uint32_t slot_num; const uint32_t domain = dev_get_domain_id(dev); const uint32_t devfn = dev->path.pci.devfn; const struct drivers_amd_opensil_mpio_config *const config = dev->chip_info; - printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n", - domain, PCI_SLOT(devfn), PCI_FUNC(devfn)); + static int ddi_port = 0; + if (is_pci(dev)) + printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n", + domain, PCI_SLOT(devfn), PCI_FUNC(devfn)); + else if (config->type == IFTYPE_DDI) + printk(BIOS_DEBUG, "Setting DDI port %u\n", ddi_port); if (config->type == IFTYPE_UNUSED) { if (is_dev_enabled(dev)) { @@ -170,9 +238,11 @@ void opensil_mpio_per_device_config(struct device *dev) return; } - static int mpio_port = 0; - MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST }; if (config->type == IFTYPE_PCIE) { + static uint32_t slot_num; + static int mpio_port = 0; + + MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST }; const MPIO_ENGINE_DATA engine_data = MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine, config->start_lane, config->end_lane, @@ -194,14 +264,40 @@ void opensil_mpio_per_device_config(struct device *dev) port.Port = port_data; port.Port.MiscControls.SbLink = config->sb_link; + + if (pcidev_get_ssid(dev)) { + mpio_data->AmdPcieSubsystemVendorID = dev->subsystem_vendor; + mpio_data->AmdPcieSubsystemDeviceID = dev->subsystem_device; + } + + if (CONFIG(DRIVERS_AMD_PROMONTORY21) && config->sb_link) + opensil_promontory21_config(&SilContext, dev); + + port.Port.AlwaysExpose = 1; + port.Port.SlotNum = ++slot_num; + mpio_data->PcieTopologyData.PortList[mpio_port] = port; + /* Update TERMINATE list */ + if (mpio_port > 0) + mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0; + mpio_port++; + } else if (config->type == IFTYPE_DDI) { + MPIO_DDI_DESCRIPTOR ddi = { .Flags = DESCRIPTOR_TERMINATE_LIST }; + const MPIO_DDI_DATA ddi_data = MPIO_DDI_DATA_INITIALIZER(config->ddi_connector, + config->aux, + config->hdp); + + if (ddi_port >= MAX_DDI_PORTS) { + printk(BIOS_WARNING, "Exceeded maximum number of DDI ports.\n"); + return; + } + + ddi.Ddi = ddi_data; + ddi_descriptor_list[ddi_port] = ddi; + /* Update TERMINATE list */ + if (ddi_port > 0) + ddi_descriptor_list[ddi_port - 1].Flags = 0; + ddi_port++; } - port.Port.AlwaysExpose = 1; - port.Port.SlotNum = ++slot_num; - mpio_data->PcieTopologyData.PortList[mpio_port] = port; - /* Update TERMINATE list */ - if (mpio_port > 0) - mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0; - mpio_port++; } void opensil_mpio_global_config(void) diff --git a/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.h b/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.h index 227d6e8a97b..6e0514c30cc 100644 --- a/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.h +++ b/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.h @@ -5,6 +5,8 @@ #include +#define MAX_DDI_PORTS 5 + /* * PHOENIX MPIO mapping * PCIE0 -> [0-19] bridges 1.1-1.5 @@ -15,6 +17,7 @@ enum mpio_type { IFTYPE_UNUSED, IFTYPE_PCIE, IFTYPE_SATA, + IFTYPE_DDI, }; /* Sync with PCIE_HOTPLUG_TYPE */ @@ -46,6 +49,41 @@ enum pcie_aspm { L0sL1, }; +enum ddi_type { + ConnDP, + ConnEDP, + ConnSingleLinkDVI, + ConnDualLinkDVI, + ConnHDMI, + ConnDpToVga, + ConnDpToLvds, + ConnNutmegDpToVga, + ConnSingleLinkDviI, + ConnDpWithTypeC, + ConnDpWithTypeCWithoutRetimer, + ConnDpWithoutTypeC, + ConnEDPToLvds, + ConnEDPToLvdsSwInit, + ConnAutoDetect, +}; + +enum ddi_aux { + DdiAux1, + DdiAux2, + DdiAux3, + DdiAux4, + DdiAux5, + DdiAux6, +}; + +enum ddi_hdp { + DdiHdp1, + DdiHdp2, + DdiHdp3, + DdiHdp4, + DdiHdp5, + DdiHdp6, +}; struct drivers_amd_opensil_mpio_config { enum mpio_type type; uint8_t start_lane; @@ -58,6 +96,10 @@ struct drivers_amd_opensil_mpio_config { uint8_t aspm_l1_2 : 1; uint8_t clock_pm : 1; uint8_t sb_link : 1; + /* DDI specific */ + enum ddi_type ddi_connector; + enum ddi_aux aux; + enum ddi_hdp hdp; }; #endif /* OPENSIL_PHOENIX_POC_MPIO_CHIP_H */ diff --git a/src/vendorcode/amd/opensil/phoenix_poc/opensil b/src/vendorcode/amd/opensil/phoenix_poc/opensil index 0f806f9815c..f0d5f2ef9a5 160000 --- a/src/vendorcode/amd/opensil/phoenix_poc/opensil +++ b/src/vendorcode/amd/opensil/phoenix_poc/opensil @@ -1 +1 @@ -Subproject commit 0f806f9815c5ed14d69acbc40202078af67964e8 +Subproject commit f0d5f2ef9a5797b4c588974dfde3e3eec7d283b2 diff --git a/src/vendorcode/amd/opensil/phoenix_poc/prom21/Makefile.mk b/src/vendorcode/amd/opensil/phoenix_poc/prom21/Makefile.mk new file mode 100644 index 00000000000..b0a411729ba --- /dev/null +++ b/src/vendorcode/amd/opensil/phoenix_poc/prom21/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_DRIVERS_AMD_PROMONTORY21) += chip_to_opensil.c + +$(obj)/ramstage/vendorcode/amd/opensil/phoenix_poc/promontory21/chip_to_opensil.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas diff --git a/src/vendorcode/amd/opensil/phoenix_poc/prom21/chip_to_opensil.c b/src/vendorcode/amd/opensil/phoenix_poc/prom21/chip_to_opensil.c new file mode 100644 index 00000000000..fb65af40f4a --- /dev/null +++ b/src/vendorcode/amd/opensil/phoenix_poc/prom21/chip_to_opensil.c @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prom21.h" + +static void prom21_boolean_to_opensil(enum prom21_boolean b, uint8_t *out) +{ + if (b == HwDefault) + return; + + *out = (b == Enable) ? 1 : 0; +} + +static uint8_t xhci_gen_to_opensil(enum prom21_xhci_gen gen) +{ + return (gen == XhciGenDefault) ? 0xf : gen - 1; +} + +static uint8_t port_gen_to_opensil(enum prom21_xhci_port_gen gen) +{ + return (gen == XhciPortGenDefault) ? 0xf : gen - 1; +} + +static void apply_usb3_phy(const struct prom21_usb3_phy *src, + PROM21_USB3_PHY_TUNING *dst) +{ + if (!src->override) + return; + + dst->PT21USB3PortGen1Swing = src->gen1_swing; + dst->PT21USB3PortGen1EmpLevelEn = src->gen1_emp_level_en; + dst->PT21USB3PortGen1EmpLevel = src->gen1_emp_level; + dst->PT21USB3PortGen1PreshootEn = src->gen1_preshoot_en; + dst->PT21USB3PortGen1Preshoot = src->gen1_preshoot; + dst->PT21USB3PortGen2Swing = src->gen2_swing; + dst->PT21USB3PortGen2Cp0EmpLevelEn = src->gen2_cp0_emp_level_en; + dst->PT21USB3PortGen2Cp0EmpLevel = src->gen2_cp0_emp_level; + dst->PT21USB3PortGen2Cp0PreshootEn = src->gen2_cp0_preshoot_en; + dst->PT21USB3PortGen2Cp0Preshoot = src->gen2_cp0_preshoot; + dst->PT21USB3PortGen2Cp13EmpLevelEn = src->gen2_cp13_emp_level_en; + dst->PT21USB3PortGen2Cp13EmpLevel = src->gen2_cp13_emp_level; + dst->PT21USB3PortGen2Cp13PreshootEn = src->gen2_cp13_preshoot_en; + dst->PT21USB3PortGen2Cp13Preshoot = src->gen2_cp13_preshoot; + dst->PT21USB3PortGen2Cp14EmpLevelEn = src->gen2_cp14_emp_level_en; + dst->PT21USB3PortGen2Cp14EmpLevel = src->gen2_cp14_emp_level; + dst->PT21USB3PortGen2Cp14PreshootEn = src->gen2_cp14_preshoot_en; + dst->PT21USB3PortGen2Cp14Preshoot = src->gen2_cp14_preshoot; + dst->PT21USB3PortGen2Cp15EmpLevelEn = src->gen2_cp15_emp_level_en; + dst->PT21USB3PortGen2Cp15EmpLevel = src->gen2_cp15_emp_level; + dst->PT21USB3PortGen2Cp15PreshootEn = src->gen2_cp15_preshoot_en; + dst->PT21USB3PortGen2Cp15Preshoot = src->gen2_cp15_preshoot; + dst->PT21USB3PortGen2Cp16EmpLevelEn = src->gen2_cp16_emp_level_en; + dst->PT21USB3PortGen2Cp16EmpLevel = src->gen2_cp16_emp_level; + dst->PT21USB3PortGen2Cp16PreshootEn = src->gen2_cp16_preshoot_en; + dst->PT21USB3PortGen2Cp16Preshoot = src->gen2_cp16_preshoot; +} + +static void apply_usb2_phy(const struct prom21_usb2_phy *src, + PROM21_USB2_PHY_TUNING *dst) +{ + if (!src->override) + return; + + dst->PT21USB2SlewRate = src->slew_rate; + dst->PT21USB2DrivingCurrent = src->driving_current; + dst->PT21USB2Termination = src->termination; +} + +static void apply_sata_phy(const struct prom21_sata_phy *src, + PROM21_SATA_PHY_TUNING *dst) +{ + if (!src->override) + return; + + dst->PT21SataPortGen1Swing = src->gen1_swing; + dst->PT21SataPortGen2Swing = src->gen2_swing; + dst->PT21SataPortGen3Swing = src->gen3_swing; + dst->PT21SataPortGen1EmpLevel = src->gen1_emp_level; + dst->PT21SataPortGen2EmpLevel = src->gen2_emp_level; + dst->PT21SataPortGen3EmpLevel = src->gen3_emp_level; +} + +static void config_usb_port_enables(struct device *xhci_dev, + PROM21_DATA_BLK *primary) +{ + struct bus *xhci_bus = xhci_dev->downstream; + if (!xhci_bus) + return; + + /* The root hub is the first (and only) child on the xHCI PCI link. */ + struct device *root_hub = xhci_bus->children; + if (!root_hub || !root_hub->downstream) + return; + + for (struct device *port = root_hub->downstream->children; + port; port = port->sibling) { + unsigned int port_type, port_id; + + if (port->path.type != DEVICE_PATH_USB) + continue; + + port_type = port->path.usb.port_type; + port_id = port->path.usb.port_id; + + if (port_type == 3 && port_id < PROM21_XHCI_NUM_USB3_PORTS) + primary->PT21Usb3Port[port_id] = port->enabled; + else if (port_type == 2 && port_id < PROM21_XHCI_NUM_USB2_PORTS) + primary->PT21Usb2Port[port_id] = port->enabled; + } +} + +void opensil_promontory21_config(SIL_CONTEXT *SilContext, struct device *root_port) +{ + PROMCLASS_DATA_BLK *prom_data = SilFindStructure(SilContext, SilId_PromClass, 0); + PROMCLASS_INPUT_BLK *input_blk; + PROM21_DATA_BLK *primary; + const struct drivers_amd_promontory21_config *cfg; + const struct prom21_pcie_config *pcie; + const struct prom21_usb_config *usb; + const struct prom21_sata_config *sata; + struct device *usp, *dsp; + size_t prom_fw_size; + int i; + + if (!prom_data) { + printk(BIOS_ERR, "Could not find OpenSIL PROM data\n"); + return; + } + + input_blk = &prom_data->PromInputBlk; + + prom_fw_size = efs_read_promontory_fw((void *)CONFIG_PROMONTORY_FW_ADDR); + if (prom_fw_size) { + input_blk->PT21FwInRamAddress = CONFIG_PROMONTORY_FW_ADDR; + input_blk->PT21FWLoading = 0; + input_blk->PT21RuninRam = 1; + } else { + input_blk->PT21FwInRamAddress = CONFIG_PROMONTORY_FW_ADDR; + input_blk->PT21FWLoading = 1; + } + + input_blk->PT21DisableUnusedPciePort = false; + input_blk->PT21ClkPMEnable = CONFIG(PCIEXP_CLK_PM); + input_blk->PT21L1Enable = CONFIG(PCIEXP_ASPM); + input_blk->PT21L1ssEnable = CONFIG(PCIEXP_L1_SUB_STATE); + + /* The USP (Upstream Switch Port) is the first PCI child of root_port. */ + if (!root_port->downstream) + return; + + usp = root_port->downstream->children; + if (!usp || !usp->chip_info) + return; + + cfg = usp->chip_info; + primary = &input_blk->Primary; + + if (pcidev_get_ssid(usp)) { + primary->PT21SsidOverride = 1; + primary->PT21PcieUspSsid = pcidev_get_ssid(usp); + } + + /* + * Walk USP's downstream PCIe bus to derive port and function enables. + * DSP devices: pci 00.0-0b.0 - PCIe ports 0-11 + * pci 0c.0 - xHCI (USB port enables come from here) + * pci 0d.0 - SATA + */ + for (dsp = usp->downstream ? usp->downstream->children : NULL; + dsp; dsp = dsp->sibling) { + unsigned int slot; + + if (dsp->path.type != DEVICE_PATH_PCI) + continue; + + slot = PCI_SLOT(dsp->path.pci.devfn); + + if (slot < PROM21_NUM_PCIE_LANES) { + /* DSP PCIe port: slot 0-11 maps to port index 0-11 */ + primary->PT21PciePortEnable[slot] = dsp->enabled; + if (dsp->enabled) + primary->PT21PcieDspSsid = pcidev_get_ssid(dsp); + } else if (dsp->path.pci.devfn == PROM21_XHCI_DEVFN) { + struct device *xhci = dsp->downstream ? dsp->downstream->children : + NULL; + primary->PT21PcieDspXhciSsid = pcidev_get_ssid(dsp); + if (xhci) { + config_usb_port_enables(xhci, primary); + primary->PT21XhciSsid = pcidev_get_ssid(xhci); + } + } else if (dsp->path.pci.devfn == PROM21_SATA_DEVFN) { + primary->PT21SataEnable = dsp->enabled ? 1 : 0; + struct device *ahci = dsp->downstream ? dsp->downstream->children : + NULL; + primary->PT21PcieDspAhciSsid = pcidev_get_ssid(dsp); + if (ahci) + primary->PT21AhciSsid = pcidev_get_ssid(ahci); + } + } + + /* PCIe configuration from chip config */ + pcie = &cfg->pcie; + + prom21_boolean_to_opensil(pcie->report_small_ltr, &primary->PT21LtrSmallEnable); + primary->PT21PcieGen1SwingEnable = pcie->gen1_swing_enable; + if (pcie->gen1_swing_enable) { + for (i = 0; i < PROM21_NUM_PCIE_LANES; i++) + primary->PT21PcieGen1Swing[i] = pcie->pcie_gen1_swing[i]; + } + + primary->PT21EqPreset = pcie->eq_preset; + primary->PT21GpioPerstEnable = pcie->gpio_perst_enable; + prom21_boolean_to_opensil(pcie->msi, &primary->PT21Msi); + prom21_boolean_to_opensil(pcie->msix, &primary->PT21Msix); + + for (i = 0; i < PROM21_NUM_PCIE_CLKREQ; i++) { + primary->PT21PcieClkreqPinSelect[i] = pcie->clkreq_pin_select[i]; + primary->PT21PcieClkreqMode[i] = pcie->clkreq_mode[i]; + } + + for (i = 0; i < PROM21_NUM_PCIE_LANES / 2; i++) + prom21_boolean_to_opensil(pcie->lane_reversal_en[i], + &primary->PT21PciePortLaneRev[i]); + + /* Only write port_target_speed when explicitly set (non-zero). */ + for (i = 0; i < PROM21_NUM_PCIE_LANES; i++) + if (pcie->port_target_speed[i]) + primary->PT21PciePortTargetSpeed[i] = pcie->port_target_speed[i]; + + /* Global SI program enable */ + prom21_boolean_to_opensil(cfg->si_prog_enable, &primary->PT21SIProgEnable); + + if (cfg->si_prog_enable == Enable) { + for (i = 0; i < PROM21_XHCI_NUM_USB3_PORTS; i++) + apply_usb3_phy(&cfg->usb3_phy[i], &primary->PT21USB3Phy[i]); + for (i = 0; i < PROM21_XHCI_NUM_USB2_PORTS / 2; i++) + apply_usb2_phy(&cfg->usb2_phy[i], &primary->PT21USB2Phy[i]); + for (i = 0; i < PROM21_NUM_SATA_PORTS; i++) + apply_sata_phy(&cfg->sata_phy[i], &primary->PT21SataPhy[i]); + } + + /* USB functional settings from chip config */ + usb = &cfg->usb; + + primary->PT21Usb3GenSelect = xhci_gen_to_opensil(usb->usb3_gen); + for (i = 0; i < PROM21_XHCI_NUM_USB3_PORTS; i++) + primary->PT21XhciPortGen[i] = port_gen_to_opensil(usb->port_gen[i]); + + prom21_boolean_to_opensil(usb->hw_lpm, &primary->PT21HW_LPM); + prom21_boolean_to_opensil(usb->dbc, &primary->PT21DbC); + + /* SATA functional settings from chip config */ + sata = &cfg->sata; + primary->PT21SataMode = sata->sata_mode; + + prom21_boolean_to_opensil(sata->aggresive_link_pm_cap, &primary->PT21SataAggrLinkPmCap); + prom21_boolean_to_opensil(sata->psc_cap, &primary->PT21SataPscCap); + prom21_boolean_to_opensil(sata->ssc_cap, &primary->PT21SataSscCap); + prom21_boolean_to_opensil(sata->hot_plug, &primary->PT21SataHotPlug); + prom21_boolean_to_opensil(sata->cccs_cap, &primary->PT21SataPTSataCCCSCap); + prom21_boolean_to_opensil(sata->msi_cap, &primary->PT21AhciMsiCap); + + for (i = 0; i < PROM21_NUM_SATA_PORTS; i++) { + primary->PT21SataPortEnable[i] = sata->port_enable[i]; + prom21_boolean_to_opensil(sata->aggressive_dev_slp[i], + &primary->PT21SataAggressiveDevSlp[i]); + } +} diff --git a/src/vendorcode/amd/opensil/phoenix_poc/prom21/prom21.h b/src/vendorcode/amd/opensil/phoenix_poc/prom21/prom21.h new file mode 100644 index 00000000000..0106ba33072 --- /dev/null +++ b/src/vendorcode/amd/opensil/phoenix_poc/prom21/prom21.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void opensil_promontory21_config(SIL_CONTEXT *SilContext, struct device *root_port); diff --git a/src/vendorcode/amd/opensil/phoenix_poc/ramstage.c b/src/vendorcode/amd/opensil/phoenix_poc/ramstage.c index 7fdf5441dbb..5e6038c6575 100644 --- a/src/vendorcode/amd/opensil/phoenix_poc/ramstage.c +++ b/src/vendorcode/amd/opensil/phoenix_poc/ramstage.c @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -71,8 +73,7 @@ static void setup_rc_manager_default(SIL_CONTEXT *SilContext) rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB; rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB; - /* MmioAbove4GLimit will be adjusted down in openSIL */ - rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(cpu_phys_address_size()); + rc_mgr_input_block->MmioAbove4GLimit = IOMMU_RESERVED_MMIO_BASE; rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0; /* Enforce remapping and address space reduction, as this is what AGESA does */ rc_mgr_input_block->AmdFabric1TbRemap = 1; @@ -146,6 +147,9 @@ static void configure_usb(SIL_CONTEXT *SilContext) if (!fch_usb_data) return; + if (pcidev_get_ssid(usb_ctrlr[0])) + fch_usb_data->XhciSsid = pcidev_get_ssid(usb_ctrlr[0]); + fch_usb_data->Xhci0Enable = is_dev_enabled(usb_ctrlr[0]); fch_usb_data->Xhci1Enable = is_dev_enabled(usb_ctrlr[1]); fch_usb_data->Usb4Host[0].Usb3HCDisable = !is_dev_enabled(usb_ctrlr[2]); @@ -286,13 +290,18 @@ WEAK_DEV_PTR(lpc_bridge); static void configure_fch_acpi(SIL_CONTEXT *SilContext) { - FCHHWACPI_INPUT_BLK *fch_hwacpi_data = SilFindStructure(SilContext, SilId_FchHwAcpiP, 0); + FCHHWACPI_INPUT_BLK *fch_hwacpi_data = SilFindStructure(SilContext, SilId_FchHwAcpi, 0); FCHCLASS_INPUT_BLK *fch_data = SilFindStructure(SilContext, SilId_FchClass, 0); + struct soc_amd_phoenix_config *cfg = config_of_soc(); struct device *smb = DEV_PTR(smbus); + struct device *xhci = DEV_PTR(xhci_0); + struct device *hda = DEV_PTR(hda); if (!fch_hwacpi_data) { printk(BIOS_ERR, "OpenSIL: FCH HW ACPI data not found\n"); } else { + fch_hwacpi_data->Xtal48MPadPowerSaving = true; + if (CONFIG_MAINBOARD_POWER_FAILURE_STATE == 2) fch_hwacpi_data->PwrFailShadow = UsePrevious; else if (CONFIG_MAINBOARD_POWER_FAILURE_STATE == 1) @@ -306,8 +315,16 @@ static void configure_fch_acpi(SIL_CONTEXT *SilContext) return; } - fch_data->Smbus.SmbusSsid = smb->subsystem_vendor | - ((uint32_t)smb->subsystem_device << 16); + if (pcidev_get_ssid(smb)) { + fch_data->Smbus.SmbusSsid = pcidev_get_ssid(smb); + fch_data->FchBldCfg.CfgSmbusSsid = pcidev_get_ssid(smb); + } + + if (pcidev_get_ssid(hda)) + fch_data->FchBldCfg.CfgAzaliaSsid = pcidev_get_ssid(hda); + + if (pcidev_get_ssid(xhci)) + fch_data->FchBldCfg.CfgXhciSsid = pcidev_get_ssid(xhci); fch_data->FchBldCfg.CfgSioPmeBaseAddress = 0; fch_data->FchBldCfg.CfgAcpiPm1EvtBlkAddr = ACPI_PM_EVT_BLK; @@ -317,7 +334,15 @@ static void configure_fch_acpi(SIL_CONTEXT *SilContext) fch_data->FchBldCfg.CfgAcpiGpe0BlkAddr = ACPI_GPE0_BLK; fch_data->FchBldCfg.CfgSmiCmdPortAddr = APM_CNT; - fch_data->WdtEnable = false; + if (CONFIG(IOAPIC_PREDEFINED_ID)) { + fch_data->CfgIoApicIdPreDefEnable = 1; + fch_data->FchIoApicId = 32; + } + + if(cfg && !(cfg->common_config.fadt_boot_arch & ACPI_FADT_8042)) + fch_data->Misc.NoneSioKbcSupport = true; + + fch_data->WdtEnable = true; /* eSPI always enabled (bit 27) */ fch_data->FchRunTime.FchDeviceEnableMap = (1 << 27); diff --git a/util/amdfwtool/amdfwread.c b/util/amdfwtool/amdfwread.c index 74cd24ed81e..6de5dde2893 100644 --- a/util/amdfwtool/amdfwread.c +++ b/util/amdfwtool/amdfwread.c @@ -707,6 +707,7 @@ static int dump_efw(const embedded_firmware *fw_header) printf("\nMisc info"); printf("\n Promontory FW: %08x", fw_header->promontory_fw_ptr); printf("\n LP Promontory FW: %08x", fw_header->lp_promontory_fw_ptr); + printf("\n Promontory19 FW: %08x", fw_header->promontory19_fw_ptr); printf("\n Vendor ID: %04x", fw_header->vendor_id); printf("\n Board ID: %04x", fw_header->board_id); printf("\n ESPI0 Config: %02x", fw_header->espi0_config); diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 0234dac95d7..17b1c4a7626 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -291,6 +291,8 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_USBDP, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_USBSS, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_USB4, .level = PSP_LVL2 | PSP_LVL2_AB }, + { .type = AMD_FW_PROM19, .inst = 0, .level = PSP_LVL2 | PSP_LVL2_AB}, + { .type = AMD_FW_PROM19, .inst = 1, .level = PSP_LVL2 | PSP_LVL2_AB}, { .type = AMD_FW_INVALID }, }; @@ -838,6 +840,14 @@ static void integrate_firmwares(context *ctx, case AMD_FW_XHCI: romsig->xhci_entry = RUN_CURRENT(*ctx); break; + case AMD_FW_PROM21: + if (fw_table[i].inst == 0) + romsig->promontory_fw_ptr = RUN_BASE(*ctx); + break; + case AMD_FW_PROM19: + if (fw_table[i].inst == 0) + romsig->promontory19_fw_ptr = RUN_BASE(*ctx); + break; default: /* Error */ break; @@ -1241,6 +1251,15 @@ static void integrate_psp_firmwares(context *ctx, pspdir->entries[count].addr = RUN_CURRENT(*ctx); pspdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir); + + /* Save as offsets in flash */ + if (fw_table[i].type == AMD_FW_PROM21 && fw_table[i].inst == 0) + ctx->amd_romsig_ptr->promontory_fw_ptr = + (uint32_t)RUN_OFFSET_MODE(*ctx, ctx->current, AMD_ADDR_REL_BIOS); + if (fw_table[i].type == AMD_FW_PROM19 && fw_table[i].inst == 0) + ctx->amd_romsig_ptr->promontory19_fw_ptr = + (uint32_t)RUN_OFFSET_MODE(*ctx, ctx->current, AMD_ADDR_REL_BIOS); + adjust_current_pointer(ctx, bytes, BLOB_ALIGNMENT); } @@ -1882,6 +1901,7 @@ int main(int argc, char **argv) ctx.amd_romsig_ptr->psp_bak_directory = 0; ctx.amd_romsig_ptr->promontory_fw_ptr = 0; ctx.amd_romsig_ptr->lp_promontory_fw_ptr = 0; + ctx.amd_romsig_ptr->promontory19_fw_ptr = 0; ctx.amd_romsig_ptr->vendor_id = 0; ctx.amd_romsig_ptr->board_id = 0; ctx.amd_romsig_ptr->ubu_table = 0; diff --git a/util/amdfwtool/amdfwtool.h b/util/amdfwtool/amdfwtool.h index 94852e53e9c..86010c1dfbd 100644 --- a/util/amdfwtool/amdfwtool.h +++ b/util/amdfwtool/amdfwtool.h @@ -133,6 +133,7 @@ typedef enum _amd_fw_type { AMD_FW_USBDP = 0xa4, AMD_FW_USBSS = 0xa5, AMD_FW_USB4 = 0xa6, + AMD_FW_PROM19 = 0xa7, AMD_FW_IMC = 0x200, /* Large enough to be larger than the top BHD entry type. */ AMD_FW_GEC, AMD_FW_XHCI, @@ -193,7 +194,7 @@ typedef struct _embedded_firmware { uint32_t psp_bak_directory; uint32_t promontory_fw_ptr; uint32_t lp_promontory_fw_ptr; - uint32_t reserved_38h; + uint32_t promontory19_fw_ptr; uint32_t reserved_3Ch; uint8_t spi_readmode_f15_mod_60_6f; uint8_t fast_speed_new_f15_mod_60_6f; diff --git a/util/amdfwtool/data_parse.c b/util/amdfwtool/data_parse.c index ae72145d7d8..2405a014d62 100644 --- a/util/amdfwtool/data_parse.c +++ b/util/amdfwtool/data_parse.c @@ -413,6 +413,14 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, fw_type = AMD_FW_PROM21; subprog = 0; instance = 1; + } else if (strcmp(fw_name, "PROM19_FW_FILE") == 0) { + fw_type = AMD_FW_PROM19; + subprog = 0; + instance = 0; + } else if (strcmp(fw_name, "PROM19_FW_INS1_FILE") == 0) { + fw_type = AMD_FW_PROM19; + subprog = 0; + instance = 1; } else if (strcmp(fw_name, "LSDMA_FILE") == 0) { fw_type = AMD_FW_LSDMA; subprog = 0; diff --git a/util/amdfwtool/sbom.c b/util/amdfwtool/sbom.c index 4234afa0fc7..09e6a248df0 100644 --- a/util/amdfwtool/sbom.c +++ b/util/amdfwtool/sbom.c @@ -303,6 +303,7 @@ static const char *psp_fw_type_name(amd_fw_entry *entry) case AMD_FW_GMI3_PHY: return "AMD GMI3 PHY Firmware"; case AMD_FW_MPDMA_PM: return "AMD MPDMA PM Firmware"; case AMD_FW_PROM21: return "AMD Promontory 21 Firmware"; + case AMD_FW_PROM19: return "AMD Promontory 19 Firmware"; case AMD_FW_LSDMA: return "AMD LSDMA Firmware"; case AMD_FW_C20_MP: return "AMD C20 MP Firmware"; case AMD_FW_MINIMSMU: return "AMD Mini-SMU Firmware"; diff --git a/util/amdtool/Makefile b/util/amdtool/Makefile index 7bf65ddefc5..59a28992193 100644 --- a/util/amdtool/Makefile +++ b/util/amdtool/Makefile @@ -14,7 +14,7 @@ CPPFLAGS += -I$(top)/util/amdtool CPPFLAGS += -I$(top)/src/commonlib/include -I$(top)/src/commonlib/bsd/include CPPFLAGS += -I$(top)/src/arch/x86/include -OBJS = amdtool.o gpio.o acpimmio.o spi.o lpc.o psb.o smn.o cpu.o irq.o espi.o ahci.o +OBJS = amdtool.o gpio.o acpimmio.o spi.o lpc.o psb.o smn.o cpu.o irq.o espi.o ahci.o promontory.o OS_ARCH = $(shell uname) ifeq ($(OS_ARCH), Darwin) diff --git a/util/amdtool/amdtool.c b/util/amdtool/amdtool.c index a3b44796600..e0646cb4873 100644 --- a/util/amdtool/amdtool.c +++ b/util/amdtool/amdtool.c @@ -119,7 +119,7 @@ static void print_version(void) static void print_usage(const char *name) { - printf("usage: %s [-vh?gicspGlMAa]\n", name); + printf("usage: %s [-vh?gicspGlMAaPa]\n", name); printf("\n" " -v | --version: print the version\n" " -h | --help: print this help\n\n" @@ -133,6 +133,7 @@ static void print_usage(const char *name) " -A | --acpimmio: dump southbridge ACPI MMIO registers\n" " -R | --ahci: dump southbridge AHCI registers\n" " -p | --psb: dump Platform Secure Boot state\n" + " -P | --promontory: dump Promontory 21 chipset registers\n" " -a | --all: dump all known (safe) registers\n" "\n"); exit(1); @@ -185,7 +186,7 @@ int main(int argc, char *argv[]) int dump_gpios = 0, dump_coremsrs = 0, dump_acpimmio = 0, dump_cpu = 0; int dump_spi = 0, dump_lpc = 0, show_gpio_diffs = 0, dump_psb = 0, dump_irq = 0; - int dump_ahci = 0; + int dump_ahci = 0, dump_promontory = 0; static struct option long_options[] = { {"version", 0, 0, 'v'}, @@ -200,11 +201,12 @@ int main(int argc, char *argv[]) {"ahci", 0, 0, 'R'}, {"psb", 0, 0, 'p'}, {"spi", 0, 0, 's'}, + {"promontory", 0, 0, 'P'}, {"all", 0, 0, 'a'}, {0, 0, 0, 0} }; - while ((opt = getopt_long(argc, argv, "vh?gGilcMARpsa", + while ((opt = getopt_long(argc, argv, "vh?gGilcMARpsPa", long_options, &option_index)) != EOF) { switch (opt) { case 'v': @@ -241,6 +243,9 @@ int main(int argc, char *argv[]) case 's': dump_spi = 1; break; + case 'P': + dump_promontory = 1; + break; case 'a': dump_gpios = 1; show_gpio_diffs = 1; @@ -252,6 +257,7 @@ int main(int argc, char *argv[]) dump_spi = 1; dump_psb = 1; dump_ahci = 1; + dump_promontory = 1; break; case 'h': case '?': @@ -413,6 +419,11 @@ int main(int argc, char *argv[]) printf("\n\n"); } + if (dump_promontory) { + print_promontory(pacc); + printf("\n\n"); + } + /* Clean up */ acpimmio_cleanup(); pci_free_dev(nb); diff --git a/util/amdtool/amdtool.h b/util/amdtool/amdtool.h index 490e904ca5d..8c76df20415 100644 --- a/util/amdtool/amdtool.h +++ b/util/amdtool/amdtool.h @@ -99,6 +99,19 @@ static inline void outl(uint32_t value, uint16_t port) #define PCI_DEVICE_ID_AMD_PHX_DATA_FABRIC_6 0x14f6 #define PCI_DEVICE_ID_AMD_PHX_DATA_FABRIC_7 0x14f7 +/* Promontory 21 external PCIe chipset */ +#define PCI_DEVICE_ID_AMD_PT21_USP 0x43F4 +#define PCI_DEVICE_ID_AMD_PT21_DSP 0x43F5 +#define PCI_DEVICE_ID_AMD_PT21_SATA 0x43F6 +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L1 0x43F7 +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L2 0x43F8 +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L3 0x43F9 +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L4 0x43FA +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L5 0x43FB +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L6 0x43FC +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L7 0x43FD +#define PCI_DEVICE_ID_AMD_PT21_XHCI_L8 0x43FE + #define CPUID_TURIN_C1 0x00b00f21 #define CPUID_PHOENIX_A1 0x00a70f41 #define CPUID_PHOENIX_A2 0x00a70f52 @@ -140,5 +153,6 @@ int print_acpimmio(struct pci_dev *sb); void print_psb(struct pci_dev *nb); int print_irq_routing(struct pci_dev *sb, struct pci_dev *nb); int print_ahci_devs(struct pci_access *pacc, struct pci_dev *nb); +int print_promontory(struct pci_access *pacc); #endif diff --git a/util/amdtool/espi.c b/util/amdtool/espi.c index 29495dd01c1..1448fb7da7e 100644 --- a/util/amdtool/espi.c +++ b/util/amdtool/espi.c @@ -21,9 +21,11 @@ #define ESPI1_SMN_BASE 0x02DCA000 static const io_register_t espi_cfg_registers[] = { + {0x20, 4, "ZSTATE_S0I3_VW"}, {0x2C, 4, "MASTER_CAP"}, - {0x30, 4, "GLBL_CTL0"}, - {0x34, 4, "GLBL_CTL1"}, + {0x30, 4, "GLOBAL_CONTROL0"}, + {0x34, 4, "GLOBAL_CONTROL1"}, + {0x38, 4, "MISC_CONTROL0"}, {0x40, 4, "SLAVE0_DECODE_EN"}, {0x44, 2, "IO_BASE[0]"}, {0x46, 2, "IO_BASE[1]"}, @@ -60,6 +62,10 @@ static const io_register_t espi_cfg_registers[] = { {0x95, 1, "IO_SIZE[9]"}, {0x96, 1, "IO_SIZE[10]"}, {0x97, 1, "IO_SIZE[11]"}, + {0x98, 4, "RXVW_IRQ_INACTIVE_POALRITY"}, + {0x9C, 4, "SLAVE0_RXVW"}, + {0xA0, 4, "SLAVE0_RXVW_DATA"}, + {0xA4, 4, "SLAVE0_RXVW_INDEX"}, {0xA8, 4, "SLAVE0_RXVW_MISC_CNTL"}, {0xAC, 4, "SLAVE0_RXVW_POLARITY"}, {0xB0, 2, "IO_BASE[12]"}, diff --git a/util/amdtool/gpio.c b/util/amdtool/gpio.c index 029d106ae6a..6f3f3afbbe4 100644 --- a/util/amdtool/gpio.c +++ b/util/amdtool/gpio.c @@ -130,6 +130,7 @@ const char *const tacoma_iomux_gpio_names[] = { [ 23 * 4] = "AC_PRES", "GPIO23", "GPIO23", "GPIO23", [ 24 * 4] = "USB_OC3_L", "GPIO24", "GPIO24", "GPIO24", [ 26 * 4] = "PCIE_RST0_L", "GPIO26", "GPIO26", "GPIO26", + [ 27 * 4] = "GPIO27", "PCIE_RST1_L", "GPIO27", "GPIO27", [ 29 * 4] = "SPI_TPM_CS_L", "GPIO29", "GPIO29", "GPIO29", [ 30 * 4] = "SPI_CS2_L", "ESPI_CS_L", "GPIO30", "GPIO30", [ 31 * 4] = "SPI_CS3_L", "GPIO31", "GPIO31", "GPIO31", @@ -265,7 +266,7 @@ const uint32_t tacoma_gpio_group_defaults[] = { [0x0240 / 4] = 0x00240000, 0x00000000, 0x00060000, 0x00000000, [0x0250 / 4] = 0x00060000, 0x00000000, 0x00000000, 0x00000000, [0x0260 / 4] = 0x00000000, 0x00240000, 0x00140000, 0x00240000, - [0x0260 / 4] = 0x00140000, 0x00240000, 0x00000000, 0x00000000, + [0x0270 / 4] = 0x00140000, 0x00240000, 0x00000000, 0x00000000 }; #pragma GCC diagnostic pop @@ -357,16 +358,16 @@ const char * const trigger_type[] = { static void print_iomux_reg(uint16_t addr, uint8_t reg, const char *const *gpio_names) { - printf("IOMUXx%02x: 0x%02x (%s)\n", - addr, reg, gpio_names[addr * 4 + reg]); + printf("IOMUXx%02x (GPIO%03u): 0x%02x (%s)\n", + addr, addr, reg, gpio_names[addr * 4 + reg]); } static void print_iomux_diff(const uint8_t reg, const uint8_t def, const uint8_t diff, const char *const *gpio_names) { - printf("IOMUXx%02x: 0x%02x (%s) DEFAULT\n", - reg, def, gpio_names[reg * 4 + def]); - printf("IOMUXx%02x: 0x%02x DIFF\n", reg, diff); + printf("IOMUXx%02x (GPIO%03u): 0x%02x (%s) DEFAULT\n", + reg, reg, def, gpio_names[reg * 4 + def]); + printf("IOMUXx%02x (GPIO%03u): 0x%02x DIFF\n", reg, reg, diff); } static void print_gpio_reg(uint16_t addr, uint32_t reg, bool verbose) @@ -374,7 +375,7 @@ static void print_gpio_reg(uint16_t addr, uint32_t reg, bool verbose) size_t i; const char *attr; - printf("GPIOx%04x: 0x%08"PRIx32"\n", addr * 4, reg); + printf("GPIOx%04x (GPIO%03u): 0x%08"PRIx32"\n", addr * 4, addr, reg); if (!verbose) return; @@ -398,8 +399,8 @@ static void print_gpio_reg(uint16_t addr, uint32_t reg, bool verbose) static void print_gpio_diff(const uint16_t reg, const uint32_t def, const uint32_t diff) { - printf("GPIOx%04x: 0x%08x DEFAULT\n", reg * 4, def); - printf("GPIOx%04x: 0x%08x DIFF\n", reg * 4, diff); + printf("GPIOx%04x (GPIO%03u): 0x%08x DEFAULT\n", reg * 4, reg, def); + printf("GPIOx%04x (GPIO%03u): 0x%08x DIFF\n", reg * 4, reg, diff); } static bool is_special_gpio_register(uint16_t reg, const struct gpio_group *sb_gpio_group) diff --git a/util/amdtool/lpc.c b/util/amdtool/lpc.c index e2ace6b1fd5..21abb56cbdb 100644 --- a/util/amdtool/lpc.c +++ b/util/amdtool/lpc.c @@ -6,6 +6,9 @@ #include #include #include "amdtool.h" +#include "smn.h" + +#define AMD_LPC_CFG_SMN 0x02dc6000 static const io_register_t lpc_cfg_registers[] = { {0x00, 4, "ID"}, @@ -122,5 +125,34 @@ int print_lpc(struct pci_dev *sb) } } + printf("\n======== LPC (SMN) =======\n\n"); + + for (i = 0; i < cfg_registers_size; i++) { + switch (cfg_registers[i].size) { + case 4: + printf("0x%04x: 0x%08x (%s)\n", + cfg_registers[i].addr, + smn_read32(AMD_LPC_CFG_SMN + cfg_registers[i].addr), + cfg_registers[i].name); + break; + case 2: + printf("0x%04x: 0x%04x (%s)\n", + cfg_registers[i].addr, + smn_read16(AMD_LPC_CFG_SMN + cfg_registers[i].addr), + cfg_registers[i].name); + break; + case 1: + printf("0x%04x: 0x%02x (%s)\n", + cfg_registers[i].addr, + smn_read8(AMD_LPC_CFG_SMN + cfg_registers[i].addr), + cfg_registers[i].name); + break; + default: + printf("Error: register size %d not implemented.\n", + cfg_registers[i].size); + break; + } + } + return 0; } diff --git a/util/amdtool/promontory.c b/util/amdtool/promontory.c new file mode 100644 index 00000000000..714c7f57776 --- /dev/null +++ b/util/amdtool/promontory.c @@ -0,0 +1,646 @@ +/* amdtool: dump AMD Promontory 21 chipset registers */ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Register addresses and access methods derived from: + * src/vendorcode/amd/opensil/phoenix_poc/opensil/xUSL/PROM/ + */ + +#include +#include +#include +#include "amdtool.h" + +/* Promontory 21 PCI Device IDs (AMD vendor 0x1022) */ +#define PT21_USP_DID 0x43F4 +#define PT21_SATA_DID 0x43F6 +#define PT21_XHCI_DID_MIN 0x43F7 +#define PT21_XHCI_DID_MAX 0x43FE + +/* + * Indirect register access via xHCI MMIO offsets. + * Write 3-byte address (MSB first), then read/write data byte. + * Status bit 7 = busy; poll until clear after each address byte write. + */ +#define PT21_IND_ADDR2 0x3002 +#define PT21_IND_ADDR1 0x3001 +#define PT21_IND_ADDR0 0x3000 +#define PT21_IND_DATA_R 0x3008 +#define PT21_IND_DATA_W 0x3004 +#define PT21_IND_STATUS 0x3009 +#define PT21_IND_BUSY 0x80 + +/* Promontory 21 internal (indirect) register addresses */ + +/* USB settings */ +#define PT21_PME_REG 0x18515 +#define PT21_DBC_REG 0x18A61 +/* USB port control bitmaps (1 bit per port, 0=enabled, 1=disabled) */ +#define PT21_USB_PORT_USB3 0x1C51C /* USB3 ports 0-5 */ +#define PT21_USB_PORT_USB2_L 0x1C51D /* USB2 ports 0-7 */ +#define PT21_USB_PORT_USB2_H 0x1C51E /* USB2 ports 8-11 */ + +/* PCIe / general configuration */ +/* + * Access gate for the 0x247xx register bank: write 0x86 to unlock, + * 0x00 to lock. Applies to DSP enable, SSID, CLKREQ, and SATA port regs. + */ +#define PT21_BANK_GATE 0x24788 +#define PT21_BANK_UNLOCK 0x86 +#define PT21_BANK_LOCK 0x00 +#define PT21_DSP_ENABLE 0x24734 /* 16-bit bitmap, bit N = DSP port N enabled */ +#define PT21_CLKREQ_MODE 0x24720 /* 16-bit, 2 bits per CLKREQ: mode */ +#define PT21_CLKREQ_PINSEL 0x24724 /* 32-bit, 4 bits per CLKREQ: pin select */ +/* + * Lane reversal per DSP port: PORM21_LANE_REVERSAL_REG(a) = 0x28003 + a*0x400 + * Valid for DSP ports 0..10 (PROM21_MAX_LANE_REVERSAL_DSP_NUMBER = 11) + */ +#define PT21_LANE_REV_BASE 0x28003 +#define PT21_LANE_REV_STEP 0x400 +/* PCIe Gen1 TX swing per lane: 0x2C001 + lane*0x100, lanes 0..11 */ +#define PT21_GEN1_SWING_BASE 0x2C001 +#define PT21_GEN1_SWING_STEP 0x100 +/* Thermal throttle control */ +#define PT21_THERMAL_CTRL 0x1C51F /* bit1=throttle en, bit2=gen1 applied, bit7=SI applied */ +#define PT21_THERMAL_THRESH 0x1E521 + +/* SATA */ +#define PT21_SATA_CTRL_REG 0x10151 /* bit1=SATA enabled */ +#define PT21_SATA_PORT_EN1 0x2471C /* gated: byte bitmap, bit N = port N enabled */ +#define PT21_SATA_PORT_EN2 0x2E006 /* ungated: byte bitmap */ +#define PT21_SATA_CLKREQ 0x24720 +#define PT21_SATA_CAP 0x2E000 /* 32-bit AHCI CAP register */ +#define PT21_SATA_DEVSLP 0x2E00A /* byte bitmap: bit N = port N DevSleep enabled */ +#define PT21_SATA_HOTPLUG0 0x2E0C8 /* +PortNum for ports 0-3, bit3=hotplug enabled */ +#define PT21_AHCI_MSI_CAP 0x23C34 /* 0x50=MSI enabled, 0x70=disabled */ + +/* eFUSE / silicon revision */ +#define PT21_EFUSE_REG 0x2E37B /* bit3=1 - A2, else A0/A1 */ + +/* xHCI MSI and MSI-X capability header pointer register */ +#define PT21_XHCI_MSI_CAP 0x23834 /* 0x50=MSI enabled, 0x68=disabled */ +#define PT21_XHCI_MSIX_CAP 0x23851 /* 0x68=MSI-X enabled, 0x78=disabled */ +/* + * EqPreset register: bits[1:0] hold PT21EqPreset. + * Bit6 is also used by newer firmware as a load-done flag. + */ +#define PT21_EQ_PRESET_REG 0x1E51C /* bits[1:0] = PT21EqPreset */ +/* SATA device ID (16-bit) - behind the bank access gate */ +#define PT21_SATA_DID_REG 0x24706 /* SATA function device ID */ +#define PT21_SATA_DID_RAID 0x43BD /* RAID mode device ID */ + +#define PT21_NUM_USB3_PORTS 6 +#define PT21_NUM_USB2_PORT_GROUPS 3 /* 2 ports per group */ +#define PT21_NUM_HW_LPM 3 +#define PT21_NUM_SATA_PORTS 4 +#define PT21_NUM_PCIE_LANES 12 +#define PT21_NUM_PCIE_CLKREQ 6 + +#define PT21_XHCI_MMIO_SIZE 0x4000 +#define PT21_GPIO_MMIO_SIZE 0x20 + +static const uint32_t hw_lpm_en[PT21_NUM_HW_LPM] = { + 0x1A58C, 0x1C58C, 0x1E58C +}; + +static const uint32_t usb3_gen1_swing[PT21_NUM_USB3_PORTS] = { + 0x19490, 0x1A490, 0x1B490, 0x1C490, 0x1D490, 0x1E490 +}; + +static const uint32_t usb3_gen1_ep[PT21_NUM_USB3_PORTS] = { + 0x19250, 0x1A250, 0x1B250, 0x1C250, 0x1D250, 0x1E250 +}; + +static const uint32_t usb3_gen2_swing[PT21_NUM_USB3_PORTS] = { + 0x194A0, 0x1A4A0, 0x1B4A0, 0x1C4A0, 0x1D4A0, 0x1E4A0 +}; + +static const uint32_t usb3_gen2_cp0_ep[PT21_NUM_USB3_PORTS] = { + 0x19252, 0x1A252, 0x1B252, 0x1C252, 0x1D252, 0x1E252 +}; + +static const uint32_t usb3_gen2_cp13_ep[PT21_NUM_USB3_PORTS] = { + 0x1925C, 0x1A25C, 0x1B25C, 0x1C25C, 0x1D25C, 0x1E25C +}; + +static const uint32_t usb3_gen2_cp14_ep[PT21_NUM_USB3_PORTS] = { + 0x1925E, 0x1A25E, 0x1B25E, 0x1C25E, 0x1D25E, 0x1E25E +}; + +static const uint32_t usb3_gen2_cp15_ep[PT21_NUM_USB3_PORTS] = { + 0x19260, 0x1A260, 0x1B260, 0x1C260, 0x1D260, 0x1E260 +}; + +static const uint32_t usb3_gen2_cp16_ep[PT21_NUM_USB3_PORTS] = { + 0x19262, 0x1A262, 0x1B262, 0x1C262, 0x1D262, 0x1E262 +}; + +/* + * USB2 TX regs: 4 entries per port-group (slew, drive, drive-dup, term). + * The duplicate at index 2/6/10 mirrors the driving-current register. + */ +static const uint32_t usb2_tx_reg[12] = { + 0x1A598, 0x1A599, 0x1A598, 0x1A59A, + 0x1C598, 0x1C599, 0x1C598, 0x1C59A, + 0x1E598, 0x1E599, 0x1E598, 0x1E59A +}; + +static const uint32_t sata_gen12_swing[PT21_NUM_SATA_PORTS] = { + 0x2D188, 0x2D388, 0x2D588, 0x2D788 +}; + +static const uint32_t sata_gen3_swing[PT21_NUM_SATA_PORTS] = { + 0x2D189, 0x2D389, 0x2D589, 0x2D789 +}; + +static const uint32_t sata_gen1_emph[PT21_NUM_SATA_PORTS] = { + 0x2D18B, 0x2D38B, 0x2D58B, 0x2D78B +}; + +static const uint32_t sata_gen2_emph[PT21_NUM_SATA_PORTS] = { + 0x2D18C, 0x2D38C, 0x2D58C, 0x2D78C +}; + +static const uint32_t sata_gen3_emph[PT21_NUM_SATA_PORTS] = { + 0x2D18D, 0x2D38D, 0x2D58D, 0x2D78D +}; + +static const uint32_t sata_speed_reg[PT21_NUM_SATA_PORTS] = { + 0x2D12B, 0x2D32B, 0x2D52B, 0x2D72B +}; + +/* + * USB3 port speed-select registers (r_force_superspeed in Prom21.h): + * bit2 = force_function_enable + * bits[2:0]: 0x3 = hw default (no force) + * 0x4 = force Gen1x1, 0x5 = force Gen1x2 + * 0x6 = force Gen2x1, 0x7 = force Gen2x2 + */ +static const uint32_t usb3_force_ss[PT21_NUM_USB3_PORTS] = { + 0x19211, 0x1A211, 0x1B211, 0x1C211, 0x1D211, 0x1E211 +}; + +static void pt21_wait_ready(uint8_t *mmio) +{ + unsigned int retries = 10000; + + while ((read8(mmio + PT21_IND_STATUS) & PT21_IND_BUSY) && retries--) + ; +} + +static void pt21_set_addr(uint8_t *mmio, uint32_t addr) +{ + write8(mmio + PT21_IND_ADDR2, (addr >> 16) & 0xFF); + pt21_wait_ready(mmio); + write8(mmio + PT21_IND_ADDR1, (addr >> 8) & 0xFF); + pt21_wait_ready(mmio); + write8(mmio + PT21_IND_ADDR0, addr & 0xFF); + pt21_wait_ready(mmio); +} + +/* + * Read one byte from a Promontory 21 internal register via the indirect + * access mechanism at xHCI MMIO offsets 0x3000-0x3009. + * Matches Prom21XhciReadByte() in PromAccess.c. + */ +static uint8_t pt21_read_byte(uint8_t *mmio, uint32_t addr) +{ + (void)read8(mmio + PT21_IND_STATUS); /* dummy status read */ + pt21_set_addr(mmio, addr); + return read8(mmio + PT21_IND_DATA_R); +} + +/* Read a 16-bit little-endian value via two consecutive byte reads. */ +static uint16_t pt21_read_word(uint8_t *mmio, uint32_t addr) +{ + uint16_t val; + + (void)read8(mmio + PT21_IND_STATUS); + pt21_set_addr(mmio, addr); + val = read8(mmio + PT21_IND_DATA_R); + pt21_set_addr(mmio, addr + 1); + val |= (uint16_t)read8(mmio + PT21_IND_DATA_R) << 8; + return val; +} + +/* Read a 32-bit little-endian value via four consecutive byte reads. */ +static uint32_t pt21_read_dword(uint8_t *mmio, uint32_t addr) +{ + uint32_t val = 0; + int i; + + (void)read8(mmio + PT21_IND_STATUS); + for (i = 0; i < 4; i++) { + pt21_set_addr(mmio, addr + i); + val |= (uint32_t)read8(mmio + PT21_IND_DATA_R) << (8 * i); + } + return val; +} + +/* + * Write one byte to a Promontory 21 internal register. + * Used only for the access-gate toggle (0x24788), not for configuration writes. + * Matches Prom21XhciWriteByte() in PromAccess.c. + */ +static void pt21_write_byte(uint8_t *mmio, uint32_t addr, uint8_t data) +{ + (void)read8(mmio + PT21_IND_STATUS); + pt21_set_addr(mmio, addr); + write8(mmio + PT21_IND_DATA_W, data); + pt21_wait_ready(mmio); +} + +static const char *decode_xhci_port_gen(uint8_t val) +{ + switch (val & 0x7) { + case 0x3: return "hw default"; + case 0x4: return "force Gen1x1"; + case 0x5: return "force Gen1x2"; + case 0x6: return "force Gen2x1"; + case 0x7: return "force Gen2x2"; + default: return "unknown"; + } +} + +static void dump_usb_settings(uint8_t *mmio) +{ + int i; + uint8_t val; + + printf("\n--- USB Settings ---\n"); + + val = pt21_read_byte(mmio, PT21_PME_REG); + printf(" PME Control (0x%05x): 0x%02x PME %s\n", + PT21_PME_REG, val, (val & 0x80) ? "disabled" : "enabled"); + + val = pt21_read_byte(mmio, PT21_DBC_REG); + printf(" DbC Control (0x%05x): 0x%02x\n", PT21_DBC_REG, val); + + printf(" HW LPM:\n"); + for (i = 0; i < PT21_NUM_HW_LPM; i++) { + val = pt21_read_byte(mmio, hw_lpm_en[i]); + printf(" Group %d (0x%05x): 0x%02x bits[4:1]=0x%x\n", + i, hw_lpm_en[i], val, (val >> 1) & 0xF); + } + + /* + * Register 0x1C51C layout (USBGen2by1_port_mapping[] in Prom21.h): + * bit0 = USB3 GenSelect (PT21Usb3GenSelect) + * bits[6:1] = USB3 port 0-5 disable flags (1=disabled, 0=enabled) + */ + val = pt21_read_byte(mmio, PT21_USB_PORT_USB3); + printf(" USB3 ports 0-5 (0x%05x): 0x%02x" + " (bit0=GenSelect, bits[6:1]=disabled mask)\n", + PT21_USB_PORT_USB3, val); + printf(" GenSelect (bit0): 0x%x\n", val & 0x01); + for (i = 0; i < PT21_NUM_USB3_PORTS; i++) + printf(" USB3 Port %d (bit%d): %s\n", i, i + 1, + (val & (1 << (i + 1))) ? "disabled" : "enabled"); + + val = pt21_read_byte(mmio, PT21_USB_PORT_USB2_L); + printf(" USB2 ports 0-7 (0x%05x): 0x%02x\n", PT21_USB_PORT_USB2_L, val); + for (i = 0; i < 8; i++) + printf(" USB2 Port %d: %s\n", i, + (val & (1 << i)) ? "disabled" : "enabled"); + + val = pt21_read_byte(mmio, PT21_USB_PORT_USB2_H); + printf(" USB2 ports 8-11 (0x%05x): 0x%02x\n", PT21_USB_PORT_USB2_H, val); + for (i = 0; i < 4; i++) + printf(" USB2 Port %d: %s\n", 8 + i, + (val & (1 << i)) ? "disabled" : "enabled"); + + /* + * USB3 port speed: r_force_superspeed[] registers. + * bit2=force_function_enable; bits[2:0]: 3=hw default, + * 4=Gen1x1, 5=Gen1x2, 6=Gen2x1, 7=Gen2x2. + */ + printf(" USB3 Port Speed:\n"); + for (i = 0; i < PT21_NUM_USB3_PORTS; i++) { + val = pt21_read_byte(mmio, usb3_force_ss[i]); + printf(" Port %d (0x%05x): 0x%02x %s\n", + i, usb3_force_ss[i], val, + decode_xhci_port_gen(val)); + } + + /* EqPreset: bits[1:0] of 0x1E51C */ + val = pt21_read_byte(mmio, PT21_EQ_PRESET_REG); + printf(" EqPreset (0x%05x): 0x%02x bits[1:0]=0x%x\n", + PT21_EQ_PRESET_REG, val, val & 0x3); + + /* xHCI MSI and MSI-X capability header pointer */ + val = pt21_read_byte(mmio, PT21_XHCI_MSI_CAP); + printf(" xHCI MSI (0x%05x): 0x%02x MSI %s\n", + PT21_XHCI_MSI_CAP, val, (val == 0x50) ? "enabled" : "disabled"); + val = pt21_read_byte(mmio, PT21_XHCI_MSIX_CAP); + printf(" xHCI MSI-X (0x%05x): 0x%02x MSI-X %s\n", + PT21_XHCI_MSIX_CAP, val, (val == 0x68) ? "enabled" : "disabled"); +} + +static void dump_usb3_phy(uint8_t *mmio) +{ + int i; + + printf("\n--- USB3 PHY Tuning ---\n"); + for (i = 0; i < PT21_NUM_USB3_PORTS; i++) { + printf(" Port %d:\n", i); + printf(" Gen1 Swing (0x%05x): 0x%02x\n", + usb3_gen1_swing[i], pt21_read_byte(mmio, usb3_gen1_swing[i])); + /* + * Emphasis/preshoot registers are 16-bit words: + * bits[7:4] = EmpLevel, bit3 = PreshootEn, bits[2:0] = Preshoot + * bit8 = EmpLevelEn (PT21USB3PortGen*EmpLevelEn) + * Read as word so EmpLevelEn is captured in the upper byte. + */ + printf(" Gen1 Emph/Preshoot (0x%05x): 0x%04x\n", + usb3_gen1_ep[i], pt21_read_word(mmio, usb3_gen1_ep[i])); + printf(" Gen2 Swing (0x%05x): 0x%02x\n", + usb3_gen2_swing[i], pt21_read_byte(mmio, usb3_gen2_swing[i])); + printf(" Gen2 CP0 Emph/Pre (0x%05x): 0x%04x\n", + usb3_gen2_cp0_ep[i], pt21_read_word(mmio, usb3_gen2_cp0_ep[i])); + printf(" Gen2 CP13 Emph/Pre (0x%05x): 0x%04x\n", + usb3_gen2_cp13_ep[i], pt21_read_word(mmio, usb3_gen2_cp13_ep[i])); + printf(" Gen2 CP14 Emph/Pre (0x%05x): 0x%04x\n", + usb3_gen2_cp14_ep[i], pt21_read_word(mmio, usb3_gen2_cp14_ep[i])); + printf(" Gen2 CP15 Emph/Pre (0x%05x): 0x%04x\n", + usb3_gen2_cp15_ep[i], pt21_read_word(mmio, usb3_gen2_cp15_ep[i])); + printf(" Gen2 CP16 Emph/Pre (0x%05x): 0x%04x\n", + usb3_gen2_cp16_ep[i], pt21_read_word(mmio, usb3_gen2_cp16_ep[i])); + } +} + +static void dump_usb2_phy(uint8_t *mmio) +{ + int i; + + printf("\n--- USB2 PHY Tuning ---\n"); + for (i = 0; i < PT21_NUM_USB2_PORT_GROUPS; i++) { + printf(" Port group %d (ports %d-%d):\n", i, i * 2, i * 2 + 1); + printf(" SlewRate (0x%05x): 0x%02x\n", + usb2_tx_reg[i * 4 + 0], + pt21_read_byte(mmio, usb2_tx_reg[i * 4 + 0])); + printf(" DrivingCurrent (0x%05x): 0x%02x\n", + usb2_tx_reg[i * 4 + 1], + pt21_read_byte(mmio, usb2_tx_reg[i * 4 + 1])); + printf(" Termination (0x%05x): 0x%02x\n", + usb2_tx_reg[i * 4 + 3], + pt21_read_byte(mmio, usb2_tx_reg[i * 4 + 3])); + } +} + +static void dump_pcie_config(uint8_t *mmio) +{ + int i; + uint16_t dsp_en, clkreq_mode; + uint32_t clkreq_pinsel; + uint8_t val; + + printf("\n--- PCIe DSP Configuration ---\n"); + + /* + * The 0x247xx register bank requires the access gate to be unlocked + * (write 0x86 to 0x24788) before reading, and locked again after + * (write 0x00). This matches the firmware sequence in Prom21.c / + * Prom21Sata.c for Prom21DSPortSetting / Prom21GppClockOutput. + */ + pt21_write_byte(mmio, PT21_BANK_GATE, PT21_BANK_UNLOCK); + dsp_en = pt21_read_word(mmio, PT21_DSP_ENABLE); + clkreq_mode = pt21_read_word(mmio, PT21_CLKREQ_MODE); + clkreq_pinsel = pt21_read_dword(mmio, PT21_CLKREQ_PINSEL); + pt21_write_byte(mmio, PT21_BANK_GATE, PT21_BANK_LOCK); + + printf(" DSP Port Enable (0x%05x): 0x%04x\n", PT21_DSP_ENABLE, dsp_en); + for (i = 0; i <= 12; i++) + printf(" DSP port %2d: %s\n", i, + (dsp_en & (1 << i)) ? "enabled" : "disabled"); + + printf("\n CLKREQ Mode (0x%05x): 0x%04x\n", PT21_CLKREQ_MODE, clkreq_mode); + for (i = 0; i < PT21_NUM_PCIE_CLKREQ; i++) + printf(" CLKREQ%d mode: %u\n", i, (clkreq_mode >> (i * 2)) & 0x3); + + printf("\n CLKREQ PinSel (0x%05x): 0x%08x\n", PT21_CLKREQ_PINSEL, clkreq_pinsel); + for (i = 0; i < PT21_NUM_PCIE_CLKREQ; i++) + printf(" CLKREQ%d pin: %u\n", i, (clkreq_pinsel >> (i * 4)) & 0xF); + + /* Lane reversal: one byte per DSP port, no access gate needed */ + printf("\n Lane Reversal (DSP ports 0-%d):\n", PT21_NUM_PCIE_LANES - 1); + for (i = 0; i < PT21_NUM_PCIE_LANES; i++) { + uint32_t reg = PT21_LANE_REV_BASE + i * PT21_LANE_REV_STEP; + + val = pt21_read_byte(mmio, reg); + printf(" DSP port %2d (0x%05x): 0x%02x %s\n", + i, reg, val, (val & 0x01) ? "reversed" : "normal"); + } + + /* PCIe Gen1 TX swing per lane, no access gate */ + printf("\n PCIe Gen1 TX Swing (lanes 0-%d):\n", PT21_NUM_PCIE_LANES - 1); + for (i = 0; i < PT21_NUM_PCIE_LANES; i++) { + uint32_t reg = PT21_GEN1_SWING_BASE + i * PT21_GEN1_SWING_STEP; + + val = pt21_read_byte(mmio, reg); + printf(" Lane %2d (0x%05x): 0x%02x\n", i, reg, val); + } + + /* Thermal throttle */ + val = pt21_read_byte(mmio, PT21_THERMAL_CTRL); + printf("\n Thermal Control (0x%05x): 0x%02x\n", PT21_THERMAL_CTRL, val); + printf(" Throttle enable: %s\n", (val & 0x02) ? "yes" : "no"); + printf(" Gen1 swing applied: %s\n", (val & 0x04) ? "yes" : "no"); + printf(" SI config applied: %s\n", (val & 0x80) ? "yes" : "no"); + val = pt21_read_byte(mmio, PT21_THERMAL_THRESH); + printf(" Thermal Threshold (0x%05x): 0x%02x\n", PT21_THERMAL_THRESH, val); +} + +static void dump_sata_settings(uint8_t *mmio) +{ + int i; + uint8_t val; + uint16_t sata_did; + uint32_t cap; + + printf("\n--- SATA Settings ---\n"); + + val = pt21_read_byte(mmio, PT21_SATA_CTRL_REG); + printf(" SATA Controller (0x%05x): 0x%02x SATA %s\n", + PT21_SATA_CTRL_REG, val, (val & 0x02) ? "enabled" : "disabled"); + + /* Port enable and device ID are behind the access gate */ + pt21_write_byte(mmio, PT21_BANK_GATE, PT21_BANK_UNLOCK); + val = pt21_read_byte(mmio, PT21_SATA_PORT_EN1); + sata_did = pt21_read_word(mmio, PT21_SATA_DID_REG); + pt21_write_byte(mmio, PT21_BANK_GATE, PT21_BANK_LOCK); + printf(" SATA Mode (0x%05x): 0x%04x %s\n", + PT21_SATA_DID_REG, sata_did, + (sata_did == PT21_SATA_DID_RAID) ? "RAID" : "AHCI"); + printf(" Port Enable 1 (0x%05x): 0x%02x", PT21_SATA_PORT_EN1, val); + for (i = 0; i < PT21_NUM_SATA_PORTS; i++) + printf(" P%d=%s", i, (val & (1 << i)) ? "on" : "off"); + printf("\n"); + + val = pt21_read_byte(mmio, PT21_SATA_PORT_EN2); + printf(" Port Enable 2 (0x%05x): 0x%02x", PT21_SATA_PORT_EN2, val); + for (i = 0; i < PT21_NUM_SATA_PORTS; i++) + printf(" P%d=%s", i, (val & (1 << i)) ? "on" : "off"); + printf("\n"); + + cap = pt21_read_dword(mmio, PT21_SATA_CAP); + printf(" AHCI CAP (0x%05x): 0x%08x\n", PT21_SATA_CAP, cap); + printf(" AggrLinkPmCap (bit26): %s\n", (cap & (1 << 26)) ? "yes" : "no"); + printf(" SscCap (bit14): %s\n", (cap & (1 << 14)) ? "yes" : "no"); + printf(" PscCap (bit13): %s\n", (cap & (1 << 13)) ? "yes" : "no"); + printf(" CccsCap (bit 7): %s\n", (cap & (1 << 7)) ? "yes" : "no"); + + val = pt21_read_byte(mmio, PT21_SATA_DEVSLP); + printf(" DevSleep (0x%05x): 0x%02x", PT21_SATA_DEVSLP, val); + for (i = 0; i < PT21_NUM_SATA_PORTS; i++) + printf(" P%d=%s", i, (val & (1 << i)) ? "on" : "off"); + printf("\n"); + + val = pt21_read_byte(mmio, PT21_AHCI_MSI_CAP); + printf(" AHCI MSI Cap (0x%05x): 0x%02x MSI %s\n", + PT21_AHCI_MSI_CAP, val, (val == 0x50) ? "enabled" : "disabled"); + + printf(" Hotplug per port:\n"); + for (i = 0; i < PT21_NUM_SATA_PORTS; i++) { + val = pt21_read_byte(mmio, PT21_SATA_HOTPLUG0 + i); + printf(" Port %d (0x%05x): 0x%02x hotplug %s\n", + i, PT21_SATA_HOTPLUG0 + i, val, + (val & 0x08) ? "enabled" : "disabled"); + } + + printf("\n--- SATA PHY Tuning ---\n"); + for (i = 0; i < PT21_NUM_SATA_PORTS; i++) { + printf(" Port %d:\n", i); + printf(" Gen1/2 Swing (0x%05x): 0x%02x\n", + sata_gen12_swing[i], pt21_read_byte(mmio, sata_gen12_swing[i])); + printf(" Gen3 Swing (0x%05x): 0x%02x\n", + sata_gen3_swing[i], pt21_read_byte(mmio, sata_gen3_swing[i])); + printf(" Gen1 Emph (0x%05x): 0x%02x\n", + sata_gen1_emph[i], pt21_read_byte(mmio, sata_gen1_emph[i])); + printf(" Gen2 Emph (0x%05x): 0x%02x\n", + sata_gen2_emph[i], pt21_read_byte(mmio, sata_gen2_emph[i])); + printf(" Gen3 Emph (0x%05x): 0x%02x\n", + sata_gen3_emph[i], pt21_read_byte(mmio, sata_gen3_emph[i])); + printf(" Speed Reg (0x%05x): 0x%02x\n", + sata_speed_reg[i], pt21_read_byte(mmio, sata_speed_reg[i])); + } +} + +static void dump_gpio(uint64_t gpio_phys) +{ + const uint8_t *gpio_mmio; + + if (!gpio_phys) { + printf("\n--- GPIO: BAR not assigned ---\n"); + return; + } + + gpio_mmio = map_physical(gpio_phys, PT21_GPIO_MMIO_SIZE); + if (!gpio_mmio) { + printf("\n--- GPIO: failed to map 0x%08llx ---\n", + (unsigned long long)gpio_phys); + return; + } + + printf("\n--- GPIO (MMIO base 0x%08llx) ---\n", + (unsigned long long)gpio_phys); + printf(" Direction (0x00): 0x%08x\n", read32(gpio_mmio + 0x0)); + printf(" Output (0x08): 0x%08x\n", read32(gpio_mmio + 0x8)); + + unmap_physical((void *)gpio_mmio, PT21_GPIO_MMIO_SIZE); +} + +static struct pci_dev *find_pt21_xhci(struct pci_access *pacc) +{ + struct pci_dev *dev; + + for (dev = pacc->devices; dev; dev = dev->next) { + pci_fill_info(dev, PCI_FILL_IDENT); + if (dev->vendor_id == PCI_VENDOR_ID_AMD && + dev->device_id >= PT21_XHCI_DID_MIN && + dev->device_id <= PT21_XHCI_DID_MAX) + return dev; + } + return NULL; +} + +static struct pci_dev *find_pt21_dev(struct pci_access *pacc, uint16_t device) +{ + struct pci_dev *dev; + struct pci_filter filter; + + pci_filter_init(NULL, &filter); + filter.vendor = PCI_VENDOR_ID_AMD; + filter.device = device; + + for (dev = pacc->devices; dev; dev = dev->next) + if (pci_filter_match(&filter, dev)) + return dev; + return NULL; +} + +int print_promontory(struct pci_access *pacc) +{ + struct pci_dev *usp, *xhci; + uint8_t *xhci_mmio; + uint64_t xhci_phys, gpio_phys; + uint8_t efuse; + + printf("\n============= Promontory 21 ==============\n"); + + usp = find_pt21_dev(pacc, PT21_USP_DID); + if (!usp) { + printf("No Promontory 21 USP found (1022:%04x).\n", PT21_USP_DID); + return -1; + } + + printf("Found Promontory 21 USP (%04x:%04x) at %02x:%02x.%u\n", + usp->vendor_id, usp->device_id, + usp->bus, usp->dev, usp->func); + + xhci = find_pt21_xhci(pacc); + if (!xhci) { + printf("No Promontory 21 xHCI endpoint found.\n"); + return -1; + } + + printf("Found Promontory 21 xHCI (%04x:%04x) at %02x:%02x.%u\n", + xhci->vendor_id, xhci->device_id, + xhci->bus, xhci->dev, xhci->func); + + if (find_pt21_dev(pacc, PT21_SATA_DID)) + printf("Found Promontory 21 SATA\n"); + + pci_fill_info(xhci, PCI_FILL_BASES); + xhci_phys = xhci->base_addr[0] & ~(uint64_t)0xF; + + if (!xhci_phys || xhci_phys == (uint64_t)~0ULL) { + printf("xHCI BAR0 not assigned, cannot read indirect registers.\n"); + return -1; + } + + printf("\nxHCI MMIO base: 0x%08llx\n", (unsigned long long)xhci_phys); + + xhci_mmio = map_physical(xhci_phys, PT21_XHCI_MMIO_SIZE); + if (!xhci_mmio) { + printf("Failed to map xHCI MMIO.\n"); + return -1; + } + + efuse = pt21_read_byte(xhci_mmio, PT21_EFUSE_REG); + printf("\nSilicon Revision (eFUSE 0x%05x): 0x%02x (%s)\n", + PT21_EFUSE_REG, efuse, (efuse & 0x08) ? "A2" : "A0/A1"); + + dump_pcie_config(xhci_mmio); + dump_usb_settings(xhci_mmio); + dump_usb3_phy(xhci_mmio); + dump_usb2_phy(xhci_mmio); + dump_sata_settings(xhci_mmio); + + unmap_physical((void *)xhci_mmio, PT21_XHCI_MMIO_SIZE); + + /* GPIO MMIO BAR at USP PCI config offset 0x40, 16-byte aligned */ + gpio_phys = (uint64_t)(pci_read_long(usp, 0x40) & 0xFFFFFFF0U); + dump_gpio(gpio_phys); + + return 0; +} diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c index ddcd263665d..f04c4a08f13 100644 --- a/util/cbmem/cbmem.c +++ b/util/cbmem/cbmem.c @@ -646,7 +646,7 @@ static void parse_tpm2_log(const struct tcg_efi_spec_id_event *tpm2_log, size_t } /* Dump the TPM log table in format defined by specifications */ -static void dump_tpm_std_log(void *buf) +static void dump_tpm_std_log(void *buf, size_t size) { const struct tcpa_spec_entry *tspec_entry; const struct tcg_efi_spec_id_event *tcg_spec_entry; @@ -704,10 +704,13 @@ static void dump_tpm_cb_log(void) static void dump_tpm_log(void) { uint8_t *buf; + size_t size; - if (cbmem_drv_get_cbmem_entry(CBMEM_ID_TCPA_TCG_LOG, &buf, NULL, NULL) || - cbmem_drv_get_cbmem_entry(CBMEM_ID_TPM2_TCG_LOG, &buf, NULL, NULL)) { - dump_tpm_std_log(buf); + if (cbmem_drv_get_cbmem_entry(CBMEM_ID_TCPA_TCG_LOG, &buf, &size, NULL)) { + dump_tpm_std_log(buf, size); + free(buf); + } else if (cbmem_drv_get_cbmem_entry(CBMEM_ID_TPM2_TCG_LOG, &buf, &size, NULL)) { + dump_tpm_std_log(buf, size); free(buf); } else dump_tpm_cb_log(); diff --git a/util/msi/Makefile.mk b/util/msi/Makefile.mk index 6079cbf24d8..98b382a9d6a 100644 --- a/util/msi/Makefile.mk +++ b/util/msi/Makefile.mk @@ -2,6 +2,8 @@ TOOLCPPFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler MSIROMHOLETOOL:= $(objutil)/msi/romholetool +TOOLCPPFLAGS += $(call strip_quotes, $(CONFIG_MSI_ROMHOLE_TOOL_FLAGS)) + $(MSIROMHOLETOOL): $(dir)/romholetool/romholetool.c printf " HOSTCC Creating MSI ROMHOLE tool\n" mkdir -p $(objutil)/msi diff --git a/util/msi/romholetool/romholetool.c b/util/msi/romholetool/romholetool.c index 4fa8a2341ff..8636c717716 100644 --- a/util/msi/romholetool/romholetool.c +++ b/util/msi/romholetool/romholetool.c @@ -25,7 +25,11 @@ #define FTB_SIZE 105 #define FIB_SIZE 512 #define FDP_SIZE 1024 +#ifndef MSI_ROMHOLE_BUV_SIZE #define BUV_SIZE 1024 +#else +#define BUV_SIZE MSI_ROMHOLE_BUV_SIZE +#endif #define NUM_VOLUMES 7 struct uuid_structure { @@ -73,7 +77,11 @@ struct us_entry { struct ucsc_structure { uint8_t magic[4]; // always uCsC - uint16_t length; // structure length +#ifndef MSI_ROMHOLE_32BIT_LENGTHS + uint16_t length; // length of the structure +#else + uint32_t length; // length of the structure +#endif struct us_entry entries[NUM_US_ENTRIES]; } __packed; @@ -140,7 +148,11 @@ struct ris_structure { /* Place the following struct in the ROMHOLE flash region with 64K/128K alignment */ struct msi_romhole { uint32_t magic0; // 0x10012501 +#ifndef MSI_ROMHOLE_32BIT_LENGTHS uint16_t length; // length of the structure +#else + uint32_t length; // length of the structure +#endif char magic1[4]; // always SYSD uint32_t address; // romhole address in flash uint32_t size; // romhole total size @@ -152,7 +164,9 @@ struct msi_romhole { struct type2_rw t2rw; struct ftb_structure ftb; struct fib_structure fib; +#ifndef MSI_ROMHOLE_NO_FDP struct fdp_structure fdp; +#endif struct buv_structure buv; struct ris_structure ris; // the rest is padded with 0xff by cbfstool @@ -326,11 +340,7 @@ int main(int argc, char **argv) romhole->address = romhole_addr; romhole->size = romhole_size; memset(romhole->pad0, 0xff, 48); - romhole->length = (uint16_t)sizeof(*romhole); - - // For some reason the actual data size is reduced by 64K - if (romhole_size > 0x10000) - romhole->length -= 0x10000; + romhole->length = sizeof(*romhole); // Structures @@ -365,7 +375,7 @@ int main(int argc, char **argv) // UCSC strncpy(romhole->ucsc.magic, "uCsC", 4); - romhole->ucsc.length = (uint16_t)sizeof(struct ucsc_structure); + romhole->ucsc.length = sizeof(struct ucsc_structure); for (i = 0; i < NUM_US_ENTRIES; i++) { strncpy(romhole->ucsc.entries[i].magic, "$uS", 3); // The first 6 entries are in order @@ -403,12 +413,14 @@ int main(int argc, char **argv) strncpy(romhole->fib.magic1, "$MFX", 4); memset(romhole->fib.data, 0xfa, FIB_SIZE); +#ifndef MSI_ROMHOLE_NO_FDP // FDP strncpy(romhole->fdp.magic0, "$FDP", 4); romhole->fdp.length = (uint16_t)sizeof(struct fdp_structure); strncpy(romhole->fdp.magic1, "$Fd", 3); romhole->fdp.number = 1; memset(romhole->fdp.data, 0xff, FDP_SIZE); +#endif // BUV strncpy(romhole->buv.magic0, "$BuV", 4); diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c index 80ba12ecdd8..7cec8f58610 100644 --- a/util/superiotool/nuvoton.c +++ b/util/superiotool/nuvoton.c @@ -180,8 +180,8 @@ static const struct superio_registers reg_table[] = { NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA, 0x01,EOT}}, {0x08, "PORT80 UART", - {0xe0,0xe1,0xe2,0xe3,0xe4,EOT}, - {0x80,0x00,0x00,0x10,0x00,EOT}}, + {0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,EOT}, + {0x80,0x00,0x00,0x10,0x00,0x00,EOT}}, {0x09, "GPIO8-9, GPIO1-8 Alternate Function", {0x30,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8, 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,EOT}, @@ -984,6 +984,7 @@ void probe_idregs_nuvoton(uint16_t port) uint16_t chip_id = 0; uint8_t chip_rev = 0; uint16_t iobase = 0; + uint8_t val; int i; /* Probe for the 16bit IDs first to avoid collisions */ @@ -1055,6 +1056,12 @@ void probe_idregs_nuvoton(uint16_t port) dump_data(iobase + 5, i); break; case 0xd590: /* NCT6687D-W */ + val = regval(port, 0x1d); + regwrite(port, 0x1d, val | 8); + printf("IRQ Type: 0x%02x%02x\n", regval(port, 0x10), regval(port, 0x11)); + printf("IRQ polarity: 0x%02x%02x\n", regval(port, 0x13), regval(port, 0x14)); + regwrite(port, 0x1d, val); + dump_nct6687d_gpios(port); /* One can use the APCI/BIOS register set, although the * resulting data is still the same when using software