summaryrefslogtreecommitdiff
path: root/src/southbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge')
-rw-r--r--src/southbridge/amd/pi/hudson/Makefile.inc11
-rw-r--r--src/southbridge/amd/pi/hudson/acpi/fch.asl6
-rw-r--r--src/southbridge/amd/pi/hudson/hudson.c9
-rw-r--r--src/southbridge/amd/pi/hudson/imc.c105
-rw-r--r--src/southbridge/amd/pi/hudson/imc.h31
5 files changed, 159 insertions, 3 deletions
diff --git a/src/southbridge/amd/pi/hudson/Makefile.inc b/src/southbridge/amd/pi/hudson/Makefile.inc
index 50050563f9..73b15f9555 100644
--- a/src/southbridge/amd/pi/hudson/Makefile.inc
+++ b/src/southbridge/amd/pi/hudson/Makefile.inc
@@ -45,6 +45,10 @@ ramstage-y += reset.c
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
romstage-y += early_setup.c
+ifeq ($(CONFIG_HUDSON_IMC_FWM), y)
+romstage-y += imc.c
+ramstage-y += imc.c
+endif
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c smi_util.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smi_util.c
@@ -109,10 +113,15 @@ HUDSON_PSP_DIRECTORY_POSITION=$(call int-align,\
65536)
HUDSON_PSP_DIRECTORY_SIZE=256
else ifeq ($(CONFIG_CPU_AMD_PI_00660F01), y)
+ifeq ($(CONFIG_HUDSON_IMC_FWM), y)
+HUDSON_PSP_OFFSET=131072
+else
+HUDSON_PSP_OFFSET=0
+endif
HUDSON_PSP_DIRECTORY_POSITION=$(call int-align,\
$(call int-add,\
$(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) $(CBFS_HEADER_SIZE) $(XHCI_FWM_SIZE)\
- $(CBFS_HEADER_SIZE) $(GEC_FWM_SIZE) $(CBFS_HEADER_SIZE) $(IMC_FWM_SIZE) $(CBFS_HEADER_SIZE)),\
+ $(CBFS_HEADER_SIZE) $(GEC_FWM_SIZE) $(CBFS_HEADER_SIZE) $(IMC_FWM_SIZE) $(CBFS_HEADER_SIZE) $(HUDSON_PSP_OFFSET)),\
65536)
HUDSON_PSP_DIRECTORY_SIZE=256
else
diff --git a/src/southbridge/amd/pi/hudson/acpi/fch.asl b/src/southbridge/amd/pi/hudson/acpi/fch.asl
index b4d6899c8b..cee721f1d7 100644
--- a/src/southbridge/amd/pi/hudson/acpi/fch.asl
+++ b/src/southbridge/amd/pi/hudson/acpi/fch.asl
@@ -160,9 +160,11 @@ Method(_INI, 0) {
/* Determine the OS we're running on */
OSFL()
+#if IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE)
/* TODO: It is unstable. */
- //#include "acpi/AmdImc.asl" /* Hudson IMC function */
- //ITZE() /* enable IMC Fan Control*/
+ #include "acpi/AmdImc.asl" /* Hudson IMC function */
+ ITZE() /* enable IMC Fan Control*/
+#endif
} /* End Method(_SB._INI) */
Method(OSFL, 0){
diff --git a/src/southbridge/amd/pi/hudson/hudson.c b/src/southbridge/amd/pi/hudson/hudson.c
index 9b6e6a3f83..4ef65e9ecd 100644
--- a/src/southbridge/amd/pi/hudson/hudson.c
+++ b/src/southbridge/amd/pi/hudson/hudson.c
@@ -30,6 +30,9 @@
#include "hudson.h"
#include "smbus.h"
#include "smi.h"
+#if IS_ENABLED(CONFIG_HUDSON_IMC_FWM)
+#include "fchec.h"
+#endif
/* Offsets from ACPI_MMIO_BASE
* This is defined by AGESA, but we don't include AGESA headers to avoid
@@ -130,6 +133,12 @@ static void hudson_init(void *chip_info)
static void hudson_final(void *chip_info)
{
+#if IS_ENABLED(CONFIG_HUDSON_IMC_FWM)
+ agesawrapper_fchecfancontrolservice();
+#if !IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE)
+ enable_imc_thermal_zone();
+#endif
+#endif
}
struct chip_operations southbridge_amd_pi_hudson_ops = {
diff --git a/src/southbridge/amd/pi/hudson/imc.c b/src/southbridge/amd/pi/hudson/imc.c
new file mode 100644
index 0000000000..9282c94e0c
--- /dev/null
+++ b/src/southbridge/amd/pi/hudson/imc.c
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define __SIMPLE_DEVICE__
+
+#include "imc.h"
+#include <arch/io.h>
+#include <device/device.h>
+#include <delay.h>
+#include <Porting.h>
+#include <AGESA.h>
+#include <Lib/amdlib.h>
+#include <Proc/Fch/Common/FchCommonCfg.h>
+#include <Proc/Fch/Fch.h>
+#include <Proc/Fch/FchPlatform.h>
+
+#define VACPI_MMIO_VBASE ((u8 *)ACPI_MMIO_BASE)
+
+void imc_reg_init(void)
+{
+ u8 reg8;
+ /* Init Power Management Block 2 (PM2) Registers.
+ * Check BKDG for AMD Family 16h for details. */
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x00), 0x06);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x01), 0x06);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x02), 0xf7);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x03), 0xff);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x04), 0xff);
+
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x10), 0x06);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x11), 0x06);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x12), 0xf7);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x13), 0xff);
+ write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x14), 0xff);
+
+ reg8 = pci_read_config8(PCI_DEV(0, 0x18, 0x3), 0x1E4);
+ reg8 &= 0x8F;
+ reg8 |= 0x10;
+ pci_write_config8(PCI_DEV(0, 0x18, 0x3), 0x1E4, reg8);
+}
+
+#ifndef __PRE_RAM__
+void enable_imc_thermal_zone(void)
+{
+ AMD_CONFIG_PARAMS StdHeader;
+ UINT8 FunNum;
+ UINT8 regs[9];
+ int i;
+
+ regs[0] = 0;
+ regs[1] = 0;
+ FunNum = Fun_80;
+ for (i = 0; i <= 1; i++)
+ WriteECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
+ WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader);
+ WaitForEcLDN9MailboxCmdAck(&StdHeader);
+
+ for (i = 2; i <= 9; i++)
+ ReadECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
+
+ /* enable thermal zone 0 */
+ regs[2] |= 1;
+ regs[0] = 0;
+ regs[1] = 0;
+ FunNum = Fun_81;
+ for (i = 0; i <= 9; i++)
+ WriteECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
+ WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader);
+ WaitForEcLDN9MailboxCmdAck(&StdHeader);
+}
+#endif
+
+/* Bettong Hardware Monitor Fan Control
+ * Hardware limitation:
+ * HWM will fail to read the input temperature via I2C if other
+ * software switches the I2C address. AMD recommends using IMC
+ * to control fans, instead of HWM.
+ */
+void oem_fan_control(FCH_DATA_BLOCK *FchParams)
+{
+ /* Enable IMC fan control. the recommand way */
+ imc_reg_init();
+
+ FchParams->Imc.ImcEnable = TRUE;
+ FchParams->Hwm.HwmControl = 1; /* 1 IMC, 0 HWM */
+ FchParams->Imc.ImcEnableOverWrite = 1; /* 2 disable IMC, 1 enable IMC, 0 following hw strap setting */
+
+ LibAmdMemFill(&(FchParams->Imc.EcStruct), 0, sizeof(FCH_EC), FchParams->StdHeader);
+}
diff --git a/src/southbridge/amd/pi/hudson/imc.h b/src/southbridge/amd/pi/hudson/imc.h
new file mode 100644
index 0000000000..4824ac50fd
--- /dev/null
+++ b/src/southbridge/amd/pi/hudson/imc.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef HUDSON_IMC_H
+#define HUDSON_IMC_H
+
+#include "Porting.h"
+#include "AGESA.h"
+#include <FchCommonCfg.h>
+
+void imc_reg_init(void);
+void enable_imc_thermal_zone(void);
+void oem_fan_control(FCH_DATA_BLOCK *FchParams);
+
+#endif