[coreboot] New patch to review for coreboot: 4344b7e SB800: Add IMC ROM and Fan control. Add AMD's IMC ROM and fan configuration to the build for cimx/sb800 platforms.

Martin Roth (martin@se-eng.com) gerrit at coreboot.org
Fri Dec 7 00:42:17 CET 2012


Martin Roth (martin at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1977

-gerrit

commit 4344b7e053ab2871f57cab65c84b8e57425e2f91
Author: Martin Roth <martin at se-eng.com>
Date:   Wed Dec 5 16:07:11 2012 -0700

    SB800: Add IMC ROM and Fan control.
    Add AMD's IMC ROM and fan configuration to the build for cimx/sb800 platforms.
    
    - Allows for no fan control, manual setup of SB800 Fan registers, or
      set up the IMC fan configuration.
    
    Change-Id: Ib06408d794988cbb29eed6adbeeadea8b2629bae
    Signed-off-by: Martin Roth <martin at se-eng.com>
---
 src/mainboard/amd/persimmon/fan_config.h           | 121 ++++++++
 src/southbridge/amd/cimx/sb800/Kconfig             |  56 ++++
 src/southbridge/amd/cimx/sb800/Makefile.inc        |  40 +++
 src/southbridge/amd/cimx/sb800/SBPLATFORM.h        |   4 +
 src/southbridge/amd/cimx/sb800/cfg.c               |   1 +
 src/southbridge/amd/cimx/sb800/fan.c               | 333 +++++++++++++++++++++
 src/southbridge/amd/cimx/sb800/fan.h               | 139 +++++++++
 .../amd/cimx/sb800/fan_config.example.h            | 224 ++++++++++++++
 src/southbridge/amd/cimx/sb800/late.c              |   8 +
 src/vendorcode/amd/cimx/sb800/OEM.h                |  12 +
 10 files changed, 938 insertions(+)

diff --git a/src/mainboard/amd/persimmon/fan_config.h b/src/mainboard/amd/persimmon/fan_config.h
new file mode 100644
index 0000000..d2ad1bf
--- /dev/null
+++ b/src/mainboard/amd/persimmon/fan_config.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Sage Electronic Engineering, LLC
+ *
+ * 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 _SB800_FAN_CONFIG_H_
+#define _SB800_FAN_CONFIG_H_
+
+#include <southbridge/amd/cimx/sb800/fan.h>
+
+/*****************************************************************************
+ * Initial Register values
+ ****************************************************************************/
+#define IMC_PORT_ADDRESS		0x6E	/* 0x2E and 0x6E are common */
+
+/*
+ * Set Enabled Zones, fans, and temperature sensors
+ * use 1 = enabled, 0 = disabled
+ */
+#define FAN0_ENABLED	1
+#define FAN1_ENABLED	1
+#define FAN2_ENABLED	0
+#define FAN3_ENABLED	0
+#define FAN4_ENABLED	0
+#define IMC_FAN_ZONE0_ENABLED 1
+#define IMC_FAN_ZONE1_ENABLED 1
+#define IMC_FAN_ZONE2_ENABLED 0
+#define IMC_FAN_ZONE3_ENABLED 0
+#define IMC_TEMPIN0_ENABLED 0
+#define IMC_TEMPIN1_ENABLED 0
+#define IMC_TEMPIN2_ENABLED 0
+#define IMC_TEMPIN3_ENABLED 0
+
+/* Initial Fan configuration Setting the SB800 registers directly */
+#define FAN0_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN0_FREQUENCY_REG_VALUE	FREQ_25KHZ
+#define FAN0_LOW_DUTY_REG_VALUE		0x08
+#define FAN0_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN0_CONTROL_REG_VALUE, \
+                          FAN0_FREQUENCY_REG_VALUE, FAN0_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+#define FAN1_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN1_FREQUENCY_REG_VALUE	FREQ_25KHZ
+#define FAN1_LOW_DUTY_REG_VALUE		0x10
+#define FAN1_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN1_CONTROL_REG_VALUE, \
+                          FAN1_FREQUENCY_REG_VALUE, FAN1_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+/* 8-bit I2c address of the CPU thermal sensor */
+#define SB_TSI_ADDRESS		0x98
+
+/*
+ ********** Zone 0 **********
+ */
+#define ZONE0_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT0
+#define ZONE0_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN0 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE0_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE0_HYSTERESIS	0x05	/* Degrees C Hysteresis */
+#define ZONE0_SMBUS_ADDR	SB_TSI_ADDRESS	/* Temp Sensor SMBus address */
+#define ZONE0_SMBUS_NUM		IMC_TEMP_SENSOR_ON_SMBUS_3	/* SMBUS number */
+#define ZONE0_PWM_STEP		0x01	/* Fan PWM stepping rate */
+#define ZONE0_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* T56N has a Maximum operating temperature  of 90°C */
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE0_THRESHOLDS	{ 87, 82, 77, 72, 65, 1, 0, 0, 90}
+#define ZONE0_FANSPEEDS		{100,  7,  5,  4,  3, 2, 0, 0}
+
+#define ZONE0_CONFIG_VALS	{ ZONE0_MODE1, ZONE0_MODE2, ZONE0_TEMP_OFFSET, \
+                         	  ZONE0_HYSTERESIS, ZONE0_SMBUS_ADDR, ZONE0_SMBUS_NUM, \
+                         	  ZONE0_PWM_STEP, ZONE0_RAMPING }
+
+/*
+ ********** Zone 1 **********
+ */
+#define ZONE1_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT1
+#define ZONE1_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN1 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE1_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE1_HYSTERESIS	0x05	/* Degrees C Hysteresis */
+#define ZONE1_SMBUS_ADDR	SB_TSI_ADDRESS	/* Temp Sensor SMBus address */
+#define ZONE1_SMBUS_NUM		IMC_TEMP_SENSOR_ON_SMBUS_3	/* SMBUS number*/
+#define ZONE1_PWM_STEP		0x01	/* Fan PWM stepping rate  */
+#define ZONE1_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE1_THRESHOLDS	{ 85, 80, 75, 65, 1, 0, 0, 0, 90}
+#define ZONE1_FANSPEEDS		{100, 10,  6,  4, 3, 0, 0, 0}
+
+#define ZONE1_CONFIG_VALS	{ ZONE1_MODE1, ZONE1_MODE2, ZONE1_TEMP_OFFSET, \
+                         	  ZONE1_HYSTERESIS, ZONE1_SMBUS_ADDR, ZONE1_SMBUS_NUM, \
+                         	  ZONE1_PWM_STEP, ZONE1_RAMPING }
+
+#endif /* _SB800_FAN_CONFIG_H_ */
diff --git a/src/southbridge/amd/cimx/sb800/Kconfig b/src/southbridge/amd/cimx/sb800/Kconfig
index 4ac2094..35f0e2e 100644
--- a/src/southbridge/amd/cimx/sb800/Kconfig
+++ b/src/southbridge/amd/cimx/sb800/Kconfig
@@ -130,5 +130,61 @@ config S3_VOLATILE_POS
 	  For a system with S3 feature, the BIOS needs to save some data to
 	  non-volitile storage at cold boot stage.
 
+config SB800_IMC_FWM
+	bool "Add IMC firmware"
+	default n
+	help
+	  Add SB800 / Hudson 1 IMC Firmware to support the onboard fan control.
+	  Please contact AMD to obtain the related firmware.
+
+if SB800_IMC_FWM
+
+config SB800_IMC_FWM_FILE
+	string "IMC firmware path and filename"
+	default "3rdparty/southbridge/amd/sb800/imc.bin"
+
+config SB800_FWM_POSITION
+	hex "SB800 Firmware ROM Position"
+	default 0xFFFA0000
+	help
+	  The IMC and GEC ROMs requires a 'signature' located at one of several
+	  fixed locations in memory.  These fixed locations by ROM size are:
+	  1MB ROM: 0xFFFA0000, 0xFFF20000
+	  2MB ROM: 0xFFFA0000, 0xFFF20000, 0xFFE20000
+	  4MB ROM: 0xFFFA0000, 0xFFF20000, 0xFFE20000, 0xFFC20000
+	  8MB ROM: 0xFFFA0000, 0xFFF20000, 0xFFE20000, 0xFFC20000, 0xFF820000
+
+endif  #SB800_IMC_FWM
+
+choice
+	prompt "Fan Control"
+	default SB800_NO_FAN_CONTROL
+	help
+	  Select the method of SB800 fan control to be used.  None would be
+	  for either fixed maximum speed fans connected to the SB800 or for
+	  an external chip controlling the fan speeds.  Manual control sets
+	  up the SB800 fan control registers.  IMC fan control uses the SB800
+	  IMC to actively control the fan speeds.
+
+config SB800_NO_FAN_CONTROL
+	bool "None"
+	help
+	  No SB800 Fan control - Do not set up the SB800 fan control registers.
+
+config SB800_MANUAL_FAN_CONTROL
+	bool "Manual"
+	help
+	  Set up the fan control registers for a fixed fan speed.
+
+config SB800_IMC_FAN_CONTROL
+	bool "IMC Based"
+	depends on SB800_IMC_FWM
+	help
+	  Set up the SB800 to use the IMC based Fan controller.  This requires
+	  the IMC rom from AMD.
+
+endchoice
+
+
 endif #SOUTHBRIDGE_AMD_CIMX_SB800
 
diff --git a/src/southbridge/amd/cimx/sb800/Makefile.inc b/src/southbridge/amd/cimx/sb800/Makefile.inc
index bea9763..064cbc7 100644
--- a/src/southbridge/amd/cimx/sb800/Makefile.inc
+++ b/src/southbridge/amd/cimx/sb800/Makefile.inc
@@ -27,6 +27,8 @@ romstage-y += smbus.c
 ramstage-y += cfg.c
 ramstage-y += late.c
 
+ramstage-$(CONFIG_SB800_MANUAL_FAN_CONTROL) += fan.c
+ramstage-$(CONFIG_SB800_IMC_FAN_CONTROL) += fan.c
 ramstage-$(CONFIG_HAVE_ACPI_RESUME) += spi.c
 ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
 
@@ -53,3 +55,41 @@ ifeq ($(CONFIG_SB800_SATA_RAID), y)
 	raid/misc.bin-position := $(CONFIG_RAID_MISC_ROM_POSITION)
 	raid/misc.bin-type := raw
 endif
+
+ifeq ($(CONFIG_SB800_IMC_FWM), y)
+
+# ROMSIG At ROMBASE + 0x20000:
+# +-----------+---------------+----------------+------------+
+# |0x55AA55AA |EC ROM Address |GEC ROM Address |            |
+# +-----------+---------------+----------------+------------+
+# EC ROM should be 64K aligned.
+SB800_FWM_POSITION=$(shell printf %u $(CONFIG_SB800_FWM_POSITION))
+#assume the cbfs header is less than 128 bytes.
+ROMSIG_SIZE=16
+
+SB800_IMC_POSITION_UNALIGN=$(shell echo $(SB800_FWM_POSITION) $(ROMSIG_SIZE) 128 65535 | awk '{print $$1 + $$2 + $$3 + $$4}')
+SB800_IMC_POSITION=$(shell echo $(SB800_IMC_POSITION_UNALIGN) | awk '{print $$1 - $$1 % 65536}')
+
+$(obj)/coreboot_SB800_romsig.bin: \
+			$(call strip_quotes, $(CONFIG_SB800_IMC_FWM_FILE)) \
+			$(obj)/config.h \
+			$(obj)/mainboard/$(MAINBOARDDIR)/static.c
+	echo "    SB800 FW  $@"
+	for fwm in 1437226410 \
+		$(SB800_IMC_POSITION) \
+		0 \
+		0 ; do \
+		echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done > $@
+
+cbfs-files-y += SB800/fwm
+SB800/fwm-file := $(obj)/coreboot_SB800_romsig.bin
+SB800/fwm-position := $(SB800_FWM_POSITION)
+SB800/fwm-type := raw
+
+cbfs-files-y += SB800/imc
+SB800/imc-file := $(call strip_quotes, $(CONFIG_SB800_IMC_FWM_FILE))
+SB800/imc-position := $(SB800_IMC_POSITION)
+SB800/imc-type := raw
+
+endif
diff --git a/src/southbridge/amd/cimx/sb800/SBPLATFORM.h b/src/southbridge/amd/cimx/sb800/SBPLATFORM.h
index 22d7724..1966eb4 100644
--- a/src/southbridge/amd/cimx/sb800/SBPLATFORM.h
+++ b/src/southbridge/amd/cimx/sb800/SBPLATFORM.h
@@ -57,6 +57,10 @@ typedef union _PCI_ADDR {
 #endif
 #define FIXUP_PTR(ptr)  ptr
 
+#if CONFIG_SB800_IMC_FWM
+	#define IMC_ENABLE_OVER_WRITE        0x01
+#endif
+
 #include <console/console.h>
 #include "AmdSbLib.h"
 #include "Amd.h"
diff --git a/src/southbridge/amd/cimx/sb800/cfg.c b/src/southbridge/amd/cimx/sb800/cfg.c
index 71fea67..ebc9918 100644
--- a/src/southbridge/amd/cimx/sb800/cfg.c
+++ b/src/southbridge/amd/cimx/sb800/cfg.c
@@ -112,6 +112,7 @@ void sb800_cimx_config(AMDSBCFG *sb_config)
 	sb_config->BuildParameters.PCIBSsid = PCIB_SSID;
 	sb_config->BuildParameters.SpreadSpectrumType = Spread_Spectrum_Type;
 	sb_config->BuildParameters.HpetBase = HPET_BASE_ADDRESS;
+	sb_config->BuildParameters.ImcEnableOverWrite = IMC_ENABLE_OVER_WRITE;
 
 	/* General */
 	sb_config->SpreadSpectrum = SPREAD_SPECTRUM;
diff --git a/src/southbridge/amd/cimx/sb800/fan.c b/src/southbridge/amd/cimx/sb800/fan.c
new file mode 100644
index 0000000..7eab6aa
--- /dev/null
+++ b/src/southbridge/amd/cimx/sb800/fan.c
@@ -0,0 +1,333 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Sage Electronic Engineering, LLC
+ *
+ * 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
+ */
+
+#include <southbridge/amd/cimx/cimx_util.h>
+#include <southbridge/amd/cimx/sb800/SBPLATFORM.h>
+#include <southbridge/amd/cimx/sb800/sb_cimx.h>
+#include <southbridge/amd/cimx/sb800/fan.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+
+/*
+ * For a new motherboard, copy the fan_config.example.h into the mainboard
+ * directory, rename it to fan_config.h and customize it.
+ */
+#include "fan_config.h"
+
+
+void init_sb800_MANUAL_fans(void)
+{
+	int i;
+
+	/* Init Fan 0 */
+#if FAN0_ENABLED
+	unsigned char	fan0_values[FAN_REGISTER_COUNT] = FAN0_REG_VALUES;
+
+	for (i = 0; i < FAN_REGISTER_COUNT; i++)
+		pm2_iowrite(FAN_0_OFFSET + i, fan0_values[i]);
+
+#endif
+
+	/* Init Fan 1 */
+#if FAN1_ENABLED
+	unsigned char	fan1_values[FAN_REGISTER_COUNT] = FAN1_REG_VALUES;
+
+	for (i = 0; i < FAN_REGISTER_COUNT; i++)
+		pm2_iowrite(FAN_1_OFFSET + i, fan1_values[i]);
+
+#endif
+
+	/* Init Fan 2 */
+#if FAN2_ENABLED
+	unsigned char	fan2_values[FAN_REGISTER_COUNT] = FAN2_REG_VALUES;
+
+	for (i = 0; i < FAN_REGISTER_COUNT; i++)
+		pm2_iowrite(FAN_2_OFFSET + i, fan2_values[i]);
+
+#endif
+
+	/* Init Fan 3 */
+#if FAN3_ENABLED
+	unsigned char	fan3_values[FAN_REGISTER_COUNT] = FAN3_REG_VALUES;
+
+	for (i = 0; i < FAN_REGISTER_COUNT; i++)
+		pm2_iowrite(FAN_3_OFFSET + i, fan3_values[i]);
+
+#endif
+
+	/* Init Fan 4 */
+#if FAN4_ENABLED
+	unsigned char	fan4_values[FAN_REGISTER_COUNT] = FAN4_REG_VALUES;
+
+	for (i = 0; i < FAN_REGISTER_COUNT; i++)
+		pm2_iowrite(FAN_4_OFFSET + i, fan4_values[i]);
+
+#endif
+
+
+}
+
+void init_sb800_IMC_fans(void)
+{
+
+	AMDSBCFG sb_config;
+	unsigned char *message_ptr;
+	int i;
+
+	/*
+	 * The default I/O address of the IMC configuration register index
+	 *  port is 0x6E. Change the IMC Config port I/O Address if it
+	 *  conflicts with Other Components in the system.
+	 *
+	 * Device 20, Function 3, Reg 0xA4
+	 * [0]: if 1, the address specified in IMC_PortAddress is used.
+	 * [15:1] IMC_PortAddress bits 15:1 (0x17 - address 0x2E )
+	 */
+
+	pci_write_config16(PCI_DEV(0, 20, 3), 0xA4, IMC_PORT_ADDRESS | 0x01);
+
+	/*
+	 * Do an initial manual setup of the fans for things like polarity
+	 * and frequency.
+	 */
+	init_sb800_MANUAL_fans();
+
+	/*
+	 * FLAG for Func 81/83/85/89 support (1=On,0=Off)
+	 * Bit0-3   = Func 81 Zone0-Zone3
+	 * Bit4-7   = Func 83 Zone0-Zone3
+	 * Bit8-11  = Func 85 Zone0-Zone3
+	 * Bit12-15 = Func 89 Tempin Channel0-Channel3
+	 */
+	sb_config.Pecstruct.IMCFUNSupportBitMap =
+		(IMC_FAN_ZONE0_ENABLED * 0x111) | (IMC_FAN_ZONE1_ENABLED * 0x222) |
+		(IMC_FAN_ZONE2_ENABLED * 0x444) | (IMC_FAN_ZONE3_ENABLED * 0x888) |
+		(IMC_TEMPIN0_ENABLED << 12)     | (IMC_TEMPIN1_ENABLED << 13)  |
+		(IMC_TEMPIN2_ENABLED << 14)     | (IMC_TEMPIN3_ENABLED << 15);
+
+/*
+ ********** Zone 0 **********
+ */
+#if IMC_FAN_ZONE0_ENABLED
+	unsigned char	fan0_config_vals[IMC_FAN_CONFIG_COUNT] = ZONE0_CONFIG_VALS;
+	unsigned char	fan0_thresholds[IMC_FAN_THRESHOLD_COUNT] = ZONE0_THRESHOLDS;
+	unsigned char	fan0_speeds[IMC_FAN_SPEED_COUNT]= ZONE0_FANSPEEDS;
+
+	/* EC LDN9 function 81 zone 0 */
+	sb_config.Pecstruct.MSGFun81zone0MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun81zone0MSGREG1 = IMC_ZONE0;
+	message_ptr = &sb_config.Pecstruct.MSGFun81zone0MSGREG2;
+	for (i = 0; i < IMC_FAN_CONFIG_COUNT ; i++ )
+		*(message_ptr + i) = fan0_config_vals[i];
+
+	/* EC LDN9 function 83 zone 0 - Temperature Thresholds */
+	sb_config.Pecstruct.MSGFun83zone0MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun83zone0MSGREG1 = IMC_ZONE0;
+	sb_config.Pecstruct.MSGFun83zone0MSGREGB = 0x00;
+	message_ptr = &sb_config.Pecstruct.MSGFun83zone0MSGREG2;
+	for (i = 0; i < IMC_FAN_THRESHOLD_COUNT ; i++ )
+		*(message_ptr + i) = fan0_thresholds[i];
+
+	/*EC LDN9 function 85 zone 0 - Fan Speeds */
+	sb_config.Pecstruct.MSGFun85zone0MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun85zone0MSGREG1 = IMC_ZONE0;
+	message_ptr = &sb_config.Pecstruct.MSGFun85zone0MSGREG2;
+	for (i = 0; i < IMC_FAN_SPEED_COUNT ; i++ )
+		*(message_ptr + i) = fan0_speeds[i];
+
+#endif /* IMC_FAN_ZONE0_ENABLED */
+
+/*
+ ********** Zone 1 **********
+ */
+#if IMC_FAN_ZONE1_ENABLED
+	unsigned char	fan1_config_vals[IMC_FAN_CONFIG_COUNT] = ZONE1_CONFIG_VALS;
+	unsigned char	fan1_thresholds[IMC_FAN_THRESHOLD_COUNT] = ZONE1_THRESHOLDS;
+	unsigned char	fan1_speeds[IMC_FAN_SPEED_COUNT]= ZONE1_FANSPEEDS;
+
+	/* EC LDN9 function 81 zone 1 */
+	sb_config.Pecstruct.MSGFun81zone1MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun81zone1MSGREG1 = IMC_ZONE1;
+	message_ptr = &sb_config.Pecstruct.MSGFun81zone1MSGREG2;
+	for (i = 0; i < IMC_FAN_CONFIG_COUNT ; i++ )
+		*(message_ptr + i) = fan1_config_vals[i];
+
+	/* EC LDN9 function 83 zone 1 - Temperature Thresholds */
+	sb_config.Pecstruct.MSGFun83zone1MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun83zone1MSGREG1 = IMC_ZONE1;
+	sb_config.Pecstruct.MSGFun83zone1MSGREGB = 0x00;
+	message_ptr = &sb_config.Pecstruct.MSGFun83zone1MSGREG2;
+	for (i = 0; i < IMC_FAN_THRESHOLD_COUNT ; i++ )
+		*(message_ptr + i) = fan1_thresholds[i];
+
+	/* EC LDN9 function 85 zone 1 - Fan Speeds */
+	sb_config.Pecstruct.MSGFun85zone1MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun85zone1MSGREG1 = IMC_ZONE1;
+	message_ptr = &sb_config.Pecstruct.MSGFun85zone1MSGREG2;
+	for (i = 0; i < IMC_FAN_SPEED_COUNT ; i++ )
+		*(message_ptr + i) = fan1_speeds[i];
+
+
+#endif /* IMC_FAN_ZONE1_ENABLED */
+
+
+/*
+ ********** Zone 2 **********
+ */
+#if IMC_FAN_ZONE2_ENABLED
+	unsigned char	fan2_config_vals[IMC_FAN_CONFIG_COUNT] = ZONE2_CONFIG_VALS;
+	unsigned char	fan2_thresholds[IMC_FAN_THRESHOLD_COUNT] = ZONE2_THRESHOLDS;
+	unsigned char	fan2_speeds[IMC_FAN_SPEED_COUNT]= ZONE2_FANSPEEDS;
+
+	/* EC LDN9 function 81 zone 2 */
+	sb_config.Pecstruct.MSGFun81zone2MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun81zone2MSGREG1 = IMC_ZONE2;
+	message_ptr = &sb_config.Pecstruct.MSGFun81zone2MSGREG2;
+	for (i = 0; i < IMC_FAN_CONFIG_COUNT ; i++ )
+		*(message_ptr + i) = fan2_config_vals[i];
+
+	/* EC LDN9 function 83 zone 2 */
+	sb_config.Pecstruct.MSGFun83zone2MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun83zone2MSGREG1 = IMC_ZONE2;
+	sb_config.Pecstruct.MSGFun83zone2MSGREGB = 0x00;
+	message_ptr = &sb_config.Pecstruct.MSGFun83zone2MSGREG2;
+	for (i = 0; i < IMC_FAN_THRESHOLD_COUNT ; i++ )
+		*(message_ptr + i) = fan2_thresholds[i];
+
+	/* EC LDN9 function 85 zone 2 */
+	sb_config.Pecstruct.MSGFun85zone2MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun85zone2MSGREG1 = IMC_ZONE2;
+	message_ptr = &sb_config.Pecstruct.MSGFun85zone2MSGREG2;
+	for (i = 0; i < IMC_FAN_SPEED_COUNT ; i++ )
+		*(message_ptr + i) = fan2_speeds[i];
+
+#endif /* IMC_FAN_ZONE2_ENABLED */
+
+
+/*
+ ********** Zone 3 **********
+ */
+
+#if IMC_FAN_ZONE3_ENABLED
+	unsigned char	fan3_config_vals[IMC_FAN_CONFIG_COUNT] = ZONE3_CONFIG_VALS;
+	unsigned char	fan3_thresholds[IMC_FAN_THRESHOLD_COUNT] = ZONE3_THRESHOLDS;
+	unsigned char	fan3_speeds[IMC_FAN_SPEED_COUNT]= ZONE3_FANSPEEDS;
+
+	/* EC LDN9 function 81 zone 3 */
+	sb_config.Pecstruct.MSGFun81zone3MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun81zone3MSGREG1 = IMC_ZONE3;
+	message_ptr = &sb_config.Pecstruct.MSGFun81zone3MSGREG2;
+	for (i = 0; i < IMC_FAN_CONFIG_COUNT ; i++ )
+		*(message_ptr + i) = fan3_config_vals[i];
+
+	/* EC LDN9 function 83 zone 3 */
+	sb_config.Pecstruct.MSGFun83zone3MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun83zone3MSGREG1 = IMC_ZONE3;
+	sb_config.Pecstruct.MSGFun83zone3MSGREGB = 0x00;
+	message_ptr = &sb_config.Pecstruct.MSGFun83zone3MSGREG2;
+	for (i = 0; i < IMC_FAN_THRESHOLD_COUNT ; i++ )
+		*(message_ptr + i) = fan1_thresholds[i];
+
+	/* EC LDN9 function 85 zone 3 */
+	sb_config.Pecstruct.MSGFun85zone3MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun85zone3MSGREG1 = IMC_ZONE3;
+	message_ptr = &sb_config.Pecstruct.MSGFun85zone3MSGREG2;
+	for (i = 0; i < IMC_FAN_SPEED_COUNT ; i++ )
+		*(message_ptr + i) = fan3_speeds[i];
+
+#endif /* IMC_FAN_ZONE3_ENABLED */
+
+
+	/*
+	 * EC LDN9 funtion 89 - Set HWM TEMPIN Temperature Calculation Parameters
+	 * This function provides the critical parameters of the HWM TempIn
+	 * sensors, IMC would not perform temperature measurement using those
+	 * sensors until the parameters are provided.
+	 */
+
+#if IMC_TEMPIN0_ENABLED
+	/* EC LDN9 funtion 89 TEMPIN channel 0 */
+	sb_config.Pecstruct.MSGFun89zone0MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun89zone0MSGREG1 = 0x00;
+	sb_config.Pecstruct.MSGFun89zone0MSGREG2 = ( TEMPIN0_AT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG3 = ((TEMPIN0_AT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG4 = ((TEMPIN0_AT >> 16) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG5 = ((TEMPIN0_AT >> 24) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG6 = ( TEMPIN0_CT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG7 = ((TEMPIN0_CT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG8 = ((TEMPIN0_CT >> 16)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREG9 = ((TEMPIN0_CT >> 24)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone0MSGREGA = TEMPIN0_TUNING_PARAM;
+#endif
+
+#if IMC_TEMPIN1_ENABLED
+	/* EC LDN9 funtion 89 TEMPIN channel 1 */
+	sb_config.Pecstruct.MSGFun89zone1MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun89zone1MSGREG1 = 0x01;
+	sb_config.Pecstruct.MSGFun89zone1MSGREG2 = ( TEMPIN1_AT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG3 = ((TEMPIN1_AT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG4 = ((TEMPIN1_AT >> 16) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG5 = ((TEMPIN1_AT >> 24) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG6 = ( TEMPIN1_CT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG7 = ((TEMPIN1_CT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG8 = ((TEMPIN1_CT >> 16)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREG9 = ((TEMPIN1_CT >> 24)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone1MSGREGA = TEMPIN1_TUNING_PARAM;
+#endif
+
+#if IMC_TEMPIN2_ENABLED
+	/* EC LDN9 funtion 89 TEMPIN channel 2 */
+	sb_config.Pecstruct.MSGFun89zone2MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun89zone2MSGREG1 = 0x02;
+	sb_config.Pecstruct.MSGFun89zone2MSGREG2 = ( TEMPIN2_AT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG3 = ((TEMPIN2_AT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG4 = ((TEMPIN2_AT >> 16) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG5 = ((TEMPIN2_AT >> 24) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG6 = ( TEMPIN2_CT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG7 = ((TEMPIN2_CT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG8 = ((TEMPIN2_CT >> 16)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREG9 = ((TEMPIN2_CT >> 24)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone2MSGREGA = TEMPIN2_TUNING_PARAM;
+#endif
+
+#if IMC_TEMPIN3_ENABLED
+	/* EC LDN9 funtion 89 TEMPIN channel 3 */
+	sb_config.Pecstruct.MSGFun89zone3MSGREG0 = 0x00;
+	sb_config.Pecstruct.MSGFun89zone3MSGREG1 = 0x03;
+	sb_config.Pecstruct.MSGFun89zone3MSGREG2 = ( TEMPIN3_AT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG3 = ((TEMPIN3_AT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG4 = ((TEMPIN3_AT >> 16) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG5 = ((TEMPIN3_AT >> 24) & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG6 = ( TEMPIN3_CT & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG7 = ((TEMPIN3_CT >> 8)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG8 = ((TEMPIN3_CT >> 16)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREG9 = ((TEMPIN3_CT >> 24)  & 0xff);
+	sb_config.Pecstruct.MSGFun89zone3MSGREGA = TEMPIN3_TUNING_PARAM;
+#endif
+
+
+	/* Set up the sb_config structure for the fan control initialization */
+	sb_config.StdHeader.Func = SB_EC_FANCONTROL;
+
+	AmdSbDispatcher(&sb_config);
+
+	return;
+}
+
+
diff --git a/src/southbridge/amd/cimx/sb800/fan.h b/src/southbridge/amd/cimx/sb800/fan.h
new file mode 100644
index 0000000..3faa644
--- /dev/null
+++ b/src/southbridge/amd/cimx/sb800/fan.h
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Sage Electronic Engineering, LLC
+ *
+ * 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 _SB800_FAN_H_
+#define _SB800_FAN_H_
+
+void init_sb800_IMC_fans(void);
+void init_sb800_MANUAL_fans(void);
+
+/* Fan Register Definitions */
+#define FAN_0_OFFSET				0x00
+#define FAN_1_OFFSET				0x10
+#define FAN_2_OFFSET				0x20
+#define FAN_3_OFFSET				0x30
+#define FAN_4_OFFSET				0x40
+
+#define FAN_INPUT_CONTROL_REG		0x00
+#define FAN_CONTROL_REG				0x01
+#define FAN_FREQUENCY_REG			0x02
+#define FAN_LOW_DUTY_REG			0x03
+#define FAN_MED_DUTY_REG			0x04
+#define FAN_MULTIPLIER_REG			0x05
+#define FAN_LOW_TEMP_LO_REG			0x06
+#define FAN_LOW_TEMP_HI_REG			0x07
+#define FAN_MED_TEMP_LO_REG			0x08
+#define FAN_MED_TEMP_HI_REG			0x09
+#define FAN_HIGH_TEMP_LO_REG		0x0A
+#define FAN_HIGH_TEMP_HI_REG		0x0B
+#define FAN_LINEAR_RANGE_REG		0x0C
+#define FAN_LINEAR_HOLD_REG			0x0D
+
+/* FanXInputControl Definitions */
+#define FAN_INPUT_INTERNAL_DIODE	0
+#define FAN_INPUT_TEMP0				1
+#define FAN_INPUT_TEMP1				2
+#define FAN_INPUT_TEMP2				3
+#define FAN_INPUT_TEMP3				4
+#define FAN_INPUT_TEMP0_FILTER		5
+#define FAN_INPUT_ZERO				6
+#define FAN_INPUT_DISABLED			7
+
+/* FanXControl Definitions */
+#define FAN_AUTOMODE			(1 << 0)
+#define FAN_LINEARMODE			(1 << 1)
+#define FAN_STEPMODE			0 /* ~(1 << 1) */
+#define FAN_POLARITY_HIGH		(1 << 2)
+#define FAN_POLARITY_LOW		0 /*~(1 << 2) */
+
+/* FanXLowDuty Definitions */
+#define FAN_POLARITY_HIGH_MAX_SPEED	0xff
+#define FAN_POLARITY_LOW_MAX_SPEED	0x00
+
+/* FanXFreq Definitions */
+/* Typically, fans run at 25KHz */
+#define FREQ_28KHZ			0x0
+#define FREQ_25KHZ			0x1
+#define FREQ_23KHZ			0x2
+#define FREQ_21KHZ			0x3
+#define FREQ_29KHZ			0x4
+#define FREQ_18KHZ			0x5
+/* Any value > 05h and < F7: Freq = 1/(FreqDiv * 2048 * 15ns) */
+#define FREQ_100HZ			0xF7
+#define FREQ_87HZ			0xF8
+#define FREQ_58HZ			0xF9
+#define FREQ_44HZ			0xFA
+#define FREQ_35HZ			0xFB
+#define FREQ_29HZ			0xFC
+#define FREQ_22HZ			0xFD
+#define FREQ_14HZ			0xFE
+#define FREQ_11HZ			0xFF
+
+
+/* IMC Fan Control Definitions */
+#define IMC_MODE1_FAN_ENABLED					( 1 << 0 )
+#define IMC_MODE1_FAN_IMC_CONTROLLED			( 1 << 2 )
+#define IMC_MODE1_FAN_LINEAR_MODE				( 1 << 4 )
+#define IMC_MODE1_FAN_STEP_MODE					0 /* ~( 1 << 4 ) */
+#define IMC_MODE1_NO_FANOUT						0 /* ~( 7 << 5 ) */
+#define IMC_MODE1_FANOUT0						( 1 << 5 )
+#define IMC_MODE1_FANOUT1						( 2 << 5 )
+#define IMC_MODE1_FANOUT2						( 3 << 5 )
+#define IMC_MODE1_FANOUT3						( 4 << 5 )
+#define IMC_MODE1_FANOUT4						( 5 << 5 )
+
+#define IMC_MODE2_TEMPIN_NONE					0 /* ~( 7 << 0) */
+#define IMC_MODE2_TEMPIN_0						1
+#define IMC_MODE2_TEMPIN_1						2
+#define IMC_MODE2_TEMPIN_2						3
+#define IMC_MODE2_TEMPIN_3						4
+#define IMC_MODE2_INT_TEMPIN					5
+#define IMC_MODE2_TEMPIN_SB_TSI					6
+#define IMC_MODE2_TEMPIN_OTHER					7
+#define IMC_MODE2_FANIN_NONE					0 /* ~ (7 << 3) */
+#define IMC_MODE2_FANIN0						( 1 << 3 )
+#define IMC_MODE2_FANIN1						( 2 << 3 )
+#define IMC_MODE2_FANIN2						( 3 << 3 )
+#define IMC_MODE2_FANIN3						( 4 << 3 )
+#define IMC_MODE2_FANIN4						( 5 << 3 )
+#define IMC_MODE2_TEMP_AVERAGING_ENABLED		( 1 << 6 )
+#define IMC_MODE2_TEMP_AVERAGING_DISABLED		0 /* ~( 1 << 6 ) */
+
+#define IMC_TEMP_SENSOR_ON_SMBUS_0				0
+#define IMC_TEMP_SENSOR_ON_SMBUS_2				1
+#define IMC_TEMP_SENSOR_ON_SMBUS_3				2
+#define IMC_TEMP_SENSOR_ON_SMBUS_4				3
+
+#define IMC_ZONE0								0
+#define IMC_ZONE1								1
+#define IMC_ZONE2								2
+#define IMC_ZONE3								3
+#define IMC_ZONE4								4
+
+#define IMC_TEMPIN_TUNING_DEFAULT_MODE			0
+#define IMC_TEMPIN_TUNING_HIGH_CURRENT_RATIO	1
+#define IMC_TEMPIN_TUNING_HIGH_CURRENT			2
+#define IMC_TEMPIN_TUNING_DISABLE_FILTERING		( 1 << 2 )
+
+#define IMC_FAN_THRESHOLD_COUNT					9
+#define IMC_FAN_SPEED_COUNT						8
+#define IMC_FAN_CONFIG_COUNT					8
+#define FAN_REGISTER_COUNT						15
+
+#endif
diff --git a/src/southbridge/amd/cimx/sb800/fan_config.example.h b/src/southbridge/amd/cimx/sb800/fan_config.example.h
new file mode 100644
index 0000000..7fe8032
--- /dev/null
+++ b/src/southbridge/amd/cimx/sb800/fan_config.example.h
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Sage Electronic Engineering, LLC
+ *
+ * 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 _SB800_FAN_CONFIG_H_
+#define _SB800_FAN_CONFIG_H_
+
+#include <southbridge/amd/cimx/sb800/fan.h>
+
+/*****************************************************************************
+ * Initial Register values
+ ****************************************************************************/
+#define IMC_PORT_ADDRESS		0x6E	/* 0x2E and 0x6E are common */
+
+/*
+ * Set Enabled Zones, fans, and temperature sensors
+ * use 1 = enabled, 0 = disabled
+ */
+#define FAN0_ENABLED	1
+#define FAN1_ENABLED	0
+#define FAN2_ENABLED	0
+#define FAN3_ENABLED	0
+#define FAN4_ENABLED	0
+#define IMC_FAN_ZONE0_ENABLED 1
+#define IMC_FAN_ZONE1_ENABLED 0
+#define IMC_FAN_ZONE2_ENABLED 0
+#define IMC_FAN_ZONE3_ENABLED 0
+#define IMC_TEMPIN0_ENABLED 0
+#define IMC_TEMPIN1_ENABLED 0
+#define IMC_TEMPIN2_ENABLED 0
+#define IMC_TEMPIN3_ENABLED 0
+
+/* Initial Fan configuration Setting the SB800 registers directly */
+#define FAN0_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN0_FREQUENCY_REG_VALUE	FREQ_25KHZ
+#define FAN0_LOW_DUTY_REG_VALUE		0x08
+#define FAN0_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN0_CONTROL_REG_VALUE, \
+                          FAN0_FREQUENCY_REG_VALUE, FAN0_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+#define FAN1_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN1_FREQUENCY_REG_VALUE	FREQ_25KHZ
+#define FAN1_LOW_DUTY_REG_VALUE		0x10
+#define FAN1_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN1_CONTROL_REG_VALUE, \
+                          FAN1_FREQUENCY_REG_VALUE, FAN1_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+#define FAN2_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN2_FREQUENCY_REG_VALUE	FREQ_100HZ
+#define FAN2_LOW_DUTY_REG_VALUE		FAN_POLARITY_HIGH_MAX_SPEED
+#define FAN2_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN2_CONTROL_REG_VALUE, \
+                          FAN2_FREQUENCY_REG_VALUE, FAN2_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+
+#define FAN3_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN3_FREQUENCY_REG_VALUE	FREQ_100HZ
+#define FAN3_LOW_DUTY_REG_VALUE		FAN_POLARITY_HIGH_MAX_SPEED
+#define FAN3_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN3_CONTROL_REG_VALUE, \
+                          FAN3_FREQUENCY_REG_VALUE, FAN3_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+#define FAN4_CONTROL_REG_VALUE		FAN_POLARITY_HIGH
+#define FAN4_FREQUENCY_REG_VALUE	FREQ_100HZ
+#define FAN4_LOW_DUTY_REG_VALUE		FAN_POLARITY_HIGH_MAX_SPEED
+#define FAN4_REG_VALUES { FAN_INPUT_INTERNAL_DIODE, FAN4_CONTROL_REG_VALUE, \
+                          FAN4_FREQUENCY_REG_VALUE, FAN4_LOW_DUTY_REG_VALUE, \
+                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+                          0x00, 0x00, 0x00 }
+
+
+/* 8-bit I2c address of the CPU thermal sensor */
+#define SB_TSI_ADDRESS		0x98
+
+/*
+ ********** Zone 0 **********
+ */
+#define ZONE0_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT0
+#define ZONE0_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN0 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE0_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE0_HYSTERESIS	0x05	/* Degrees C Hysteresis */
+#define ZONE0_SMBUS_ADDR	SB_TSI_ADDRESS	/* Temp Sensor SMBus address */
+#define ZONE0_SMBUS_NUM		IMC_TEMP_SENSOR_ON_SMBUS_3	/* SMBUS number */
+#define ZONE0_PWM_STEP		0x01	/* Fan PWM stepping rate */
+#define ZONE0_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* T56N has a Maximum operating temperature  of 90°C */
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE0_THRESHOLDS	{ 87, 82, 77, 65, 1, 0, 0, 0, 90}
+#define ZONE0_FANSPEEDS		{100,  7,  5,  3, 2, 0, 0, 0}
+
+#define ZONE0_CONFIG_VALS	{ ZONE0_MODE1, ZONE0_MODE2, ZONE0_TEMP_OFFSET, \
+                         	  ZONE0_HYSTERESIS, ZONE0_SMBUS_ADDR, ZONE0_SMBUS_NUM, \
+                         	  ZONE0_PWM_STEP, ZONE0_RAMPING }
+
+/*
+ ********** Zone 1 **********
+ */
+#define ZONE1_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT1
+#define ZONE1_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN1 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE1_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE1_HYSTERESIS	0x05	/* Degrees C Hysteresis */
+#define ZONE1_SMBUS_ADDR	SB_TSI_ADDRESS	/* Temp Sensor SMBus address */
+#define ZONE1_SMBUS_NUM		IMC_TEMP_SENSOR_ON_SMBUS_3	/* SMBUS number*/
+#define ZONE1_PWM_STEP		0x01	/* Fan PWM stepping rate  */
+#define ZONE1_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE1_THRESHOLDS	{ 87, 82, 77, 65, 1, 0, 0, 0, 90}
+#define ZONE1_FANSPEEDS		{100, 15, 12, 10, 4, 0, 0, 0}
+
+#define ZONE1_CONFIG_VALS	{ ZONE1_MODE1, ZONE1_MODE2, ZONE1_TEMP_OFFSET, \
+                         	  ZONE1_HYSTERESIS, ZONE1_SMBUS_ADDR, ZONE1_SMBUS_NUM, \
+                         	  ZONE1_PWM_STEP, ZONE1_RAMPING }
+
+
+/*
+ ********** Zone 2 **********
+ */
+#define ZONE2_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT2
+#define ZONE2_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN2 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE2_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE2_HYSTERESIS	0x05	/* Degrees C Hysteresis */
+#define ZONE2_SMBUS_ADDR	SB_TSI_ADDRESS	/* 8 bit SMBUS Address for SMBus based temperature sensor such as SB-TSI */
+#define ZONE2_SMBUS_NUM		0x02	/* SMBUS number from the southbridge: 2 = SCLK3/SDATA3 */
+#define ZONE2_PWM_STEP		0x01	/* Fan PWM stepping rate in unit of PWM level percentage */
+#define ZONE2_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE2_THRESHOLDS	{ 80, 70, 60, 50, 40, 30, 20,  1, 100}
+#define ZONE2_FANSPEEDS		{100, 80, 60, 50, 40, 30, 20, 10}
+
+#define ZONE2_CONFIG_VALS	{ ZONE2_MODE1, ZONE2_MODE2, ZONE2_TEMP_OFFSET, \
+                              ZONE2_HYSTERESIS, ZONE2_SMBUS_ADDR, ZONE2_SMBUS_NUM, \
+                              ZONE2_PWM_STEP, ZONE2_RAMPING }
+
+
+/*
+ ********** Zone 3 **********
+ */
+#define ZONE3_MODE1			IMC_MODE1_FAN_ENABLED | \
+                   			IMC_MODE1_FAN_IMC_CONTROLLED | \
+                   			IMC_MODE1_FAN_STEP_MODE | \
+                   			IMC_MODE1_FANOUT3
+#define ZONE3_MODE2			IMC_MODE2_TEMPIN_SB_TSI | \
+                   			IMC_MODE2_FANIN3 | \
+                   			IMC_MODE2_TEMP_AVERAGING_DISABLED
+#define ZONE3_TEMP_OFFSET	0x00	/* No temp offset */
+#define ZONE3_HYSTERESIS	0x00	/* Degrees C Hysteresis */
+#define ZONE3_SMBUS_ADDR	0x98	/* 8 bit SMBUS Address for SMBus based temperature sensor such as SB-TSI */
+#define ZONE3_SMBUS_NUM		0x02	/* SMBUS number from the southbridge: 2 = SCLK3/SDATA3 */
+#define ZONE3_PWM_STEP		0x01	/* Fan PWM stepping rate in unit of PWM level percentage */
+#define ZONE3_RAMPING		0x00	/* Disable Fan PWM ramping and stepping */
+
+/* ZONEX_THRESHOLDS - _AC0 - _AC7, _CRT - Temp Threshold in degrees C */
+/* ZONEX_FANSPEEDS - Fan speeds as a percentage */
+#define ZONE3_THRESHOLDS	{ 80, 70, 60, 50, 40, 30, 20,  1, 100}
+#define ZONE3_FANSPEEDS		{100, 80, 60, 50, 40, 30, 20, 10}
+
+#define ZONE3_CONFIG_VALS	{ ZONE3_MODE1, ZONE3_MODE2, ZONE3_TEMP_OFFSET, \
+                              ZONE3_HYSTERESIS, ZONE3_SMBUS_ADDR, ZONE3_SMBUS_NUM, \
+                              ZONE3_PWM_STEP, ZONE3_RAMPING }
+
+
+/*
+ ********** Tempin configuration  **********
+ * These need to be configured if any of the thermal zones use a
+ * TEMPIN sensor in their MODE2 configuration
+ */
+
+#define TEMPIN0_AT 0x00000000
+#define TEMPIN0_CT 0x00000000
+#define TEMPIN0_TUNING_PARAM IMC_TEMPIN_TUNING_DEFAULT_MODE
+
+#define TEMPIN1_AT 0x00000000
+#define TEMPIN1_CT 0x00000000
+#define TEMPIN1_TUNING_PARAM IMC_TEMPIN_TUNING_DEFAULT_MODE
+
+#define TEMPIN2_AT 0x00000000
+#define TEMPIN2_CT 0x00000000
+#define TEMPIN2_TUNING_PARAM IMC_TEMPIN_TUNING_DEFAULT_MODE
+
+#define TEMPIN3_AT 0x00000000
+#define TEMPIN3_CT 0x00000000
+#define TEMPIN3_TUNING_PARAM IMC_TEMPIN_TUNING_DEFAULT_MODE
+
+#endif /* _SB800_FAN_CONFIG_H_ */
diff --git a/src/southbridge/amd/cimx/sb800/late.c b/src/southbridge/amd/cimx/sb800/late.c
index 6067e39..4b5cc2d 100644
--- a/src/southbridge/amd/cimx/sb800/late.c
+++ b/src/southbridge/amd/cimx/sb800/late.c
@@ -32,6 +32,7 @@
 #include "chip.h"		/* struct southbridge_amd_cimx_sb800_config */
 #include "sb_cimx.h"		/* AMD CIMX wrapper entries */
 #include "smbus.h"
+#include "fan.h"
 
 /*implement in mainboard.c*/
 void set_pcie_reset(void);
@@ -313,6 +314,13 @@ void sb_Before_Pci_Init(void)
 {
 	sb_config->StdHeader.Func = SB_BEFORE_PCI_INIT;
 	AmdSbDispatcher(sb_config);
+
+#if CONFIG_SB800_IMC_FAN_CONTROL
+	init_sb800_IMC_fans();
+#elif CONFIG_SB800_MANUAL_FAN_CONTROL
+	init_sb800_MANUAL_fans();
+#endif
+
 }
 
 void sb_After_Pci_Init(void)
diff --git a/src/vendorcode/amd/cimx/sb800/OEM.h b/src/vendorcode/amd/cimx/sb800/OEM.h
index c2d8670..27fe586 100644
--- a/src/vendorcode/amd/cimx/sb800/OEM.h
+++ b/src/vendorcode/amd/cimx/sb800/OEM.h
@@ -293,3 +293,15 @@
 #ifndef Spread_Spectrum_Type
   #define Spread_Spectrum_Type         0x00
 #endif
+
+
+/**
+ *    Imc Enable OverWrite
+ *    2 - by default strapping
+ *    1 - On
+ *    0 - Off
+ */
+#ifndef IMC_ENABLE_OVER_WRITE
+  #define IMC_ENABLE_OVER_WRITE        0x02
+#endif
+




More information about the coreboot mailing list