diff --git a/src/drivers/siemens/nc_fpga/Kconfig b/src/drivers/siemens/nc_fpga/Kconfig index 1cd797772f..f4f1e972ef 100644 --- a/src/drivers/siemens/nc_fpga/Kconfig +++ b/src/drivers/siemens/nc_fpga/Kconfig @@ -5,3 +5,8 @@ config DRIVER_SIEMENS_NC_FPGA config NC_FPGA_NOTIFY_CB_READY bool default n + +config NC_FPGA_POST_CODE + bool + default n + select EARLY_PCI_BRIDGE diff --git a/src/drivers/siemens/nc_fpga/Makefile.inc b/src/drivers/siemens/nc_fpga/Makefile.inc index ac2875f52f..95ec00aedc 100644 --- a/src/drivers/siemens/nc_fpga/Makefile.inc +++ b/src/drivers/siemens/nc_fpga/Makefile.inc @@ -1,3 +1,9 @@ ## SPDX-License-Identifier: GPL-2.0-only ramstage-$(CONFIG_DRIVER_SIEMENS_NC_FPGA) += nc_fpga.c + +all-$(CONFIG_NC_FPGA_POST_CODE) += nc_fpga_early.c + +ifeq ($(CONFIG_NC_FPGA_POST_CODE),y) +CPPFLAGS_common += -I$(src)/drivers/siemens/nc_fpga +endif diff --git a/src/drivers/siemens/nc_fpga/nc_fpga.c b/src/drivers/siemens/nc_fpga/nc_fpga.c index 08e88565c1..0b4c7d47ea 100644 --- a/src/drivers/siemens/nc_fpga/nc_fpga.c +++ b/src/drivers/siemens/nc_fpga/nc_fpga.c @@ -142,9 +142,21 @@ static void set_fw_done(void *unused) BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, set_fw_done, NULL); #endif +static void nc_fpga_set_resources(struct device *dev) +{ + pci_dev_set_resources(dev); + + if (CONFIG(NC_FPGA_POST_CODE)) { + /* Re-initialize base address after set_resources for POST display + to work properly.*/ + nc_fpga_remap(pci_read_config32(dev, PCI_BASE_ADDRESS_0) & ~0xf); + } +} + + static struct device_operations nc_fpga_ops = { .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, + .set_resources = nc_fpga_set_resources, .enable_resources = pci_dev_enable_resources, .init = nc_fpga_init, }; diff --git a/src/drivers/siemens/nc_fpga/nc_fpga.h b/src/drivers/siemens/nc_fpga/nc_fpga.h index 2096de79b7..39cc04e993 100644 --- a/src/drivers/siemens/nc_fpga/nc_fpga.h +++ b/src/drivers/siemens/nc_fpga/nc_fpga.h @@ -17,6 +17,7 @@ #define NC_DIAG_FW_DONE 0x10000 #define NC_BL_BRIGHTNESS_OFFSET 0x88 #define NC_BL_PWM_OFFSET 0x8C +#define NC_FPGA_POST_OFFSET 0xE0 #define NC_FANMON_CTRL_OFFSET 0x400 #define MAX_NUM_SENSORS 8 @@ -58,4 +59,7 @@ typedef struct { uint32_t fanmon; } __packed fan_ctrl_t; +void nc_fpga_post(uint8_t value); +void nc_fpga_remap(uint32_t new_mmio); + #endif /* _SIEMENS_NC_FPGA_H_ */ diff --git a/src/drivers/siemens/nc_fpga/nc_fpga_early.c b/src/drivers/siemens/nc_fpga/nc_fpga_early.c new file mode 100644 index 0000000000..6ec0349922 --- /dev/null +++ b/src/drivers/siemens/nc_fpga/nc_fpga_early.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +#include "nc_fpga.h" + +static DEVTREE_CONST uint32_t fpga_bar = CONFIG_EARLY_PCI_MMIO_BASE; +static bool nc_fpga_present = false; + +int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base) +{ + pci_devfn_t pci_dev = PCI_DEV(bus, dev, 0); + uint32_t id = pci_s_read_config32(pci_dev, PCI_VENDOR_ID); + + if (id != (0x4091 << 16 | PCI_VENDOR_ID_SIEMENS)) + return -1; + + /* Setup base address for BAR0. */ + pci_s_write_config32(pci_dev, PCI_BASE_ADDRESS_0, mmio_base); + /* Enable memory access for pci_dev. */ + u16 reg16 = pci_s_read_config16(pci_dev, PCI_COMMAND); + reg16 |= PCI_COMMAND_MEMORY; + pci_s_write_config16(pci_dev, PCI_COMMAND, reg16); + nc_fpga_present = true; + + return 0; +} + +void nc_fpga_remap(uint32_t new_mmio) +{ +#if ENV_RAMSTAGE + fpga_bar = new_mmio; +#endif +} + +void nc_fpga_post(uint8_t value) +{ + /* The function pci_earyl_device_probe is called in bootblock and romstage. Make sure + that in these stages the initialization code was successful before the POST code + value is written to the register. */ + if ((ENV_BOOTBLOCK || ENV_ROMSTAGE) && nc_fpga_present == false) + return; + write32((void *)(fpga_bar + NC_FPGA_POST_OFFSET), value); +}