[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