summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/siemens/nc_fpga/Kconfig5
-rw-r--r--src/drivers/siemens/nc_fpga/Makefile.inc6
-rw-r--r--src/drivers/siemens/nc_fpga/nc_fpga.c14
-rw-r--r--src/drivers/siemens/nc_fpga/nc_fpga.h4
-rw-r--r--src/drivers/siemens/nc_fpga/nc_fpga_early.c49
5 files changed, 77 insertions, 1 deletions
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 <arch/mmio.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <types.h>
+
+#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);
+}