amd/stoneyridge: Add warm reset detection

Extend the existing reset handling features in Stoney Ridge to plan for,
and recognize, warm resets.  The ColdRstDet bit is always zero on a cold
reset, and is intended as a mechanism for the BIOS to determine the type
of a reset that occurred.

Set ColdRstDet=1 after all cores have been initialized, so that any
subsequent reset may be identified as warm/cold.  A later patch will check
the value during mp_init.

Change-Id: I90255918de03018c9f090bff1e56a8bda5e7365e
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/27924
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
diff --git a/src/soc/amd/stoneyridge/cpu.c b/src/soc/amd/stoneyridge/cpu.c
index 7fff120..52b1c9c 100644
--- a/src/soc/amd/stoneyridge/cpu.c
+++ b/src/soc/amd/stoneyridge/cpu.c
@@ -113,6 +113,8 @@
 
 	/* The flash is now no longer cacheable. Reset to WP for performance. */
 	mtrr_use_temp_range(FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
+
+	set_warm_reset_flag();
 }
 
 static void model_15_init(struct device *dev)
diff --git a/src/soc/amd/stoneyridge/include/soc/northbridge.h b/src/soc/amd/stoneyridge/include/soc/northbridge.h
index 666be10..56ae363 100644
--- a/src/soc/amd/stoneyridge/include/soc/northbridge.h
+++ b/src/soc/amd/stoneyridge/include/soc/northbridge.h
@@ -30,6 +30,7 @@
 # define CPU_CNT_MASK		0x1f /*  CpuCnt + 1 = no. CPUs */
 #define HT_INIT_CONTROL		0x6c
 # define HTIC_BIOSR_DETECT	((1 << 5) | (1 << 9) | (1 << 10))
+# define HTIC_COLD_RST_DET	BIT(4)
 
 /* NB IOAPIC registers */
 #define NB_IOAPIC_INDEX		0xf8
@@ -116,5 +117,7 @@
 void nb_ioapic_write(unsigned int index, uint32_t value);
 void *get_ap_entry_ptr(void);
 void set_ap_entry_ptr(void *entry);
+void set_warm_reset_flag(void);
+int is_warm_reset(void);
 
 #endif /* __PI_STONEYRIDGE_NORTHBRIDGE_H__ */
diff --git a/src/soc/amd/stoneyridge/reset.c b/src/soc/amd/stoneyridge/reset.c
index a133a88..738ec59 100644
--- a/src/soc/amd/stoneyridge/reset.c
+++ b/src/soc/amd/stoneyridge/reset.c
@@ -21,6 +21,21 @@
 #include <device/pci_ops.h>
 #include <soc/southbridge.h>
 
+void set_warm_reset_flag(void)
+{
+	u32 htic;
+	htic = pci_read_config32(SOC_HT_DEV, HT_INIT_CONTROL);
+	htic |= HTIC_COLD_RST_DET;
+	pci_write_config32(SOC_HT_DEV, HT_INIT_CONTROL, htic);
+}
+
+int is_warm_reset(void)
+{
+	u32 htic;
+	htic = pci_read_config32(SOC_HT_DEV, HT_INIT_CONTROL);
+	return !!(htic & HTIC_COLD_RST_DET);
+}
+
 /* Clear bits 5, 9 & 10, used to signal the reset type */
 static void clear_bios_reset(void)
 {
@@ -42,6 +57,7 @@
 
 void do_soft_reset(void)
 {
+	set_warm_reset_flag();
 	clear_bios_reset();
 
 	/* Assert reset signals only. */