Martin Roth ([email protected]) just uploaded a new patch set to gerrit, which 
you can find at http://review.coreboot.org/1977

-gerrit

commit 4344b7e053ab2871f57cab65c84b8e57425e2f91
Author: Martin Roth <[email protected]>
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 <[email protected]>
---
 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
+

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to