soc/intel/xeon_sp: Add HDA disable support

Currently the HDA device can neither be disabled using softstraps
nor can it be disabled by using FSP UPDs. Add code to disable it in
coreboot when it's marked as 'off' in coreboot's devicetree.

TEST: Device 00:1f.3 is hidden and platform boots into OS without issue.

Change-Id: Ifa1422d653cf81ee6faf2bdda27a471c2084642b
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77873
Reviewed-by: David Hendricks <david.hendricks@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/xeon_sp/ebg/Makefile.inc b/src/soc/intel/xeon_sp/ebg/Makefile.inc
index ea29e2d..ac73acb 100644
--- a/src/soc/intel/xeon_sp/ebg/Makefile.inc
+++ b/src/soc/intel/xeon_sp/ebg/Makefile.inc
@@ -1,7 +1,7 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
 bootblock-y += soc_gpio.c soc_pch.c
-romstage-y += soc_gpio.c soc_pmutil.c
+romstage-y += soc_gpio.c soc_pmutil.c soc_pch.c
 ramstage-y += lockdown.c soc_gpio.c soc_pch.c soc_pmutil.c
 
 CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/ebg/include
diff --git a/src/soc/intel/xeon_sp/ebg/include/soc/azalia_device.h b/src/soc/intel/xeon_sp/ebg/include/soc/azalia_device.h
new file mode 100644
index 0000000..911ff15
--- /dev/null
+++ b/src/soc/intel/xeon_sp/ebg/include/soc/azalia_device.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef DEVICE_AZALIA_H
+#define DEVICE_AZALIA_H
+
+#define HDA_PCS			0x54
+#define  HDA_PCS_PS_D3HOT	3
+
+#endif /* DEVICE_AZALIA_H */
diff --git a/src/soc/intel/xeon_sp/ebg/include/soc/pmc.h b/src/soc/intel/xeon_sp/ebg/include/soc/pmc.h
index 4362ce5..59c2d73 100644
--- a/src/soc/intel/xeon_sp/ebg/include/soc/pmc.h
+++ b/src/soc/intel/xeon_sp/ebg/include/soc/pmc.h
@@ -50,5 +50,7 @@
 #define  SCIS_IRQ23		7
 #define ST_PG_FDIS1		0x1e20
 #define  ST_FDIS_LK		(1 << 31)
+#define NST_PG_FDIS1		0x1e28
+#define  NST_FDIS_DSP		(1 << 23)
 
 #endif
diff --git a/src/soc/intel/xeon_sp/ebg/include/soc/soc_pch.h b/src/soc/intel/xeon_sp/ebg/include/soc/soc_pch.h
index 2d87be3..acb1785 100644
--- a/src/soc/intel/xeon_sp/ebg/include/soc/soc_pch.h
+++ b/src/soc/intel/xeon_sp/ebg/include/soc/soc_pch.h
@@ -4,5 +4,6 @@
 #define _SOC_SOC_PCH_H_
 
 void pch_lock_dmictl(void);
+void pch_disable_hda(void);
 
 #endif /* _SOC_SOC_PCH_H_ */
diff --git a/src/soc/intel/xeon_sp/ebg/soc_pch.c b/src/soc/intel/xeon_sp/ebg/soc_pch.c
index d99516f..a40af7a 100644
--- a/src/soc/intel/xeon_sp/ebg/soc_pch.c
+++ b/src/soc/intel/xeon_sp/ebg/soc_pch.c
@@ -4,10 +4,13 @@
 #include <soc/pci_devs.h>
 #include <soc/pcr_ids.h>
 #include <intelblocks/pcr.h>
+#include <intelblocks/pmclib.h>
 #include <intelblocks/rtc.h>
 #include <intelblocks/p2sb.h>
+#include <soc/azalia_device.h>
 #include <soc/bootblock.h>
 #include <soc/soc_pch.h>
+#include <soc/pch.h>
 #include <soc/pmc.h>
 #include <console/console.h>
 
@@ -59,3 +62,23 @@
 	pcr_write32(PID_DMI, PCR_DMI_DMICTL, reg32 | PCR_DMI_DMICTL_SRLOCK);
 	pcr_or32(PID_DMI, PCR_DMI_MISC_PORT_CFG, MISC_PORT_CFG_LOCK);
 }
+
+#define PCR_PSFX_T0_SHDW_PCIEN		0x1C
+#define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS	(1 << 8)
+#define PSF3_HDA_BASE_ADDRESS		0x280
+
+void pch_disable_hda(void)
+{
+	/* Ensure memory, io, and bus master are all disabled */
+	pci_and_config16(PCH_DEV_HDA, PCI_COMMAND, ~(PCI_COMMAND_MASTER |
+			 PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+	/* Put controller to D3 */
+	pci_or_config32(PCH_DEV_HDA, HDA_PCS, HDA_PCS_PS_D3HOT);
+	/* Disable DSP in PMC */
+	pmc_or_mmio32(NST_PG_FDIS1, NST_FDIS_DSP);
+	/* Hide PCI function */
+	pcr_or32(PID_PSF3, PSF3_HDA_BASE_ADDRESS + PCR_PSFX_T0_SHDW_PCIEN,
+		 PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);
+
+	printk(BIOS_INFO, "%s: Disabled HDA device 00:1f.3\n", __func__);
+}
diff --git a/src/soc/intel/xeon_sp/spr/romstage.c b/src/soc/intel/xeon_sp/spr/romstage.c
index 8abac91..2b377a4 100644
--- a/src/soc/intel/xeon_sp/spr/romstage.c
+++ b/src/soc/intel/xeon_sp/spr/romstage.c
@@ -15,6 +15,7 @@
 #include <hob_memmap.h>
 #include <soc/romstage.h>
 #include <soc/pci_devs.h>
+#include <soc/soc_pch.h>
 #include <soc/intel/common/smbios.h>
 #include <string.h>
 #include <soc/soc_util.h>
@@ -280,6 +281,10 @@
 		mupd->FspmConfig.EnforcePopulationPor = 0x1;
 		mupd->FspmConfig.EnforceDdrMemoryFreqPor = 0x0;
 	}
+
+	/* SPR-FSP has no UPD to disable HDA, so do it manually here... */
+	if (!is_devfn_enabled(PCH_DEVFN_HDA))
+		pch_disable_hda();
 }
 
 static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)