aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx/sb900/Hwm.c
diff options
context:
space:
mode:
authorefdesign98 <efdesign98@gmail.com>2011-06-16 16:39:30 -0700
committerMarc Jones <marcj303@gmail.com>2011-06-21 22:38:39 +0200
commitee39ea7e7edf9699f1bae1b2708ad6816f054817 (patch)
treee2de6cd600b1b8d4a657202962d8bc2e348ec67f /src/vendorcode/amd/cimx/sb900/Hwm.c
parentb0969d65e675f7c7a3004fc3f6fc154f22e73d44 (diff)
Add AMD SB900 CIMx code
This code is added to support the AMD SB900 southbridge. Change-Id: I7dc5e13a53ffd479dcea4e05e8c8631096e2ba91 Signed-off-by: Frank Vibrans <frank.vibrans@amd.com> Signed-off-by: efdesign98 <efdesign98@gmail.com> Reviewed-on: http://review.coreboot.org/41 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/cimx/sb900/Hwm.c')
-rwxr-xr-xsrc/vendorcode/amd/cimx/sb900/Hwm.c578
1 files changed, 578 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/sb900/Hwm.c b/src/vendorcode/amd/cimx/sb900/Hwm.c
new file mode 100755
index 0000000000..8f0992ff05
--- /dev/null
+++ b/src/vendorcode/amd/cimx/sb900/Hwm.c
@@ -0,0 +1,578 @@
+/**
+ * @file
+ *
+ * Southbridge Initial routine
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-SB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*;********************************************************************************
+;
+; Copyright (c) 2011, Advanced Micro Devices, Inc.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; * Neither the name of Advanced Micro Devices, Inc. nor the names of
+; its contributors may be used to endorse or promote products derived
+; from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+;*********************************************************************************/
+
+#include "SbPlatform.h"
+#include "cbtypes.h"
+//
+// Declaration of local functions
+//
+VOID
+hwmInitRegister (
+ IN AMDSBCFG* pConfig
+ );
+
+VOID
+hwmGetRawData (
+ IN AMDSBCFG* pConfig
+ );
+
+VOID
+hwmCaculate (
+ IN AMDSBCFG* pConfig
+ );
+
+VOID
+hwmGetCalibrationFactor (
+ IN AMDSBCFG* pConfig
+ );
+
+VOID
+hwmProcessParameter (
+ IN AMDSBCFG* pConfig
+ );
+
+VOID
+hwmSetRegister (
+ IN AMDSBCFG* pConfig
+ );
+
+
+HWM_temp_par_struct tempParDefault[] = {
+ { 5219, 27365 , 0 },
+ { 5222, 27435 , 0 },
+ { 5219, 27516 , BIT0 }, //High Ratio
+ { 5221, 27580 , BIT1 }, //High Current
+ { 5123, 27866 , 0 }
+};
+
+//#ifndef NO_HWM_SUPPORT
+/**
+ * hwmInitRegister - Init Hardware Monitor Register.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmInitRegister (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT32 LinearRangeOutLimit;
+
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xB2, AccWidthUint8, 0, 0x55);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xB3, AccWidthUint8, 0, 0x55);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x91, AccWidthUint8, 0, 0x55);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x92, AccWidthUint8, 0, 0x55);
+
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x00, AccWidthUint8, 0, 0x06);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x10, AccWidthUint8, 0, 0x06);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x20, AccWidthUint8, 0, 0x06);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x30, AccWidthUint8, 0, 0x06);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x40, AccWidthUint8, 0, 0x06);
+
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x66, AccWidthUint8, 0, 0x01);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x6B, AccWidthUint8, 0, 0x01);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x70, AccWidthUint8, 0, 0x01);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x75, AccWidthUint8, 0, 0x01);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0x7A, AccWidthUint8, 0, 0x01);
+
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xE6, AccWidthUint8, 0xff, 0x02);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xF8, AccWidthUint8, 0, 0x05);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xF9, AccWidthUint8, 0, 0x06);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xFF, AccWidthUint8, 0, 0x42);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xE9, AccWidthUint8, 0, 0xFF);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xEB, AccWidthUint8, 0, 0x1F);
+ //2.13 HWM Sensor Clk
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xEF, AccWidthUint8, 0, 0x0A);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + 0xFB, AccWidthUint8, 0, 0x00);
+
+ //2.9 Enhancement of FanOut0 Control
+ //check for fanLinearEnhanceEn
+ if (pConfig->hwm.fanLinearEnhanceEn == 0) {
+ RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG50, AccWidthUint32, ~ BIT11, BIT11);
+ LinearRangeOutLimit = (UINT32) (pConfig->hwm.fanLinearRangeOutLimit);
+ LinearRangeOutLimit = LinearRangeOutLimit << 20;
+ RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGB4, AccWidthUint32, 0xFF0FFFFF, LinearRangeOutLimit);
+ } else {
+ RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG50, AccWidthUint32, ~ BIT11, 0);
+ }
+ //check for fanLinearHoldFix
+ if (pConfig->hwm.fanLinearHoldFix == 0) {
+ RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG50, AccWidthUint32, ~ BIT20, BIT20);
+ } else {
+ RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG50, AccWidthUint32, ~ BIT20, 0);
+ }
+}
+
+
+/**
+ * hwmSbtsiAutoPolling - Hardware Monitor Auto Poll SB-TSI.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmSbtsiAutoPolling (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 dbValue;
+ UINT16 smbusBase;
+
+ smbusBase = (UINT16) (pConfig->BuildParameters.Smbus0BaseAddress);
+ if (pConfig->hwm.hwmSbtsiAutoPoll == 1) {
+ hwmSbtsiAutoPollingPause (pConfig);
+
+ RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG2E, AccWidthUint8, ~(BIT1 + BIT2), BIT2);
+ dbValue = 0xff;
+ WriteIO (smbusBase, AccWidthUint8, &dbValue);
+ dbValue = 0x08;
+ WriteIO (smbusBase + 2, AccWidthUint8, &dbValue);
+ dbValue = 0x09;
+ WriteIO (smbusBase + 3, AccWidthUint8, &dbValue);
+ dbValue = 0x98;
+ WriteIO (smbusBase + 4, AccWidthUint8, &dbValue);
+ if ( IsSbA11 () ) {
+ dbValue = 0x00;
+ } else {
+ dbValue = 0x20;
+ }
+ WriteIO (smbusBase + 5, AccWidthUint8, &dbValue);
+ dbValue = 0x48;
+ WriteIO (smbusBase + 2, AccWidthUint8, &dbValue);
+
+ ReadIO (smbusBase + 0, AccWidthUint8, &dbValue);
+ while ( dbValue & BIT0 ) {
+ ReadIO (smbusBase + 0, AccWidthUint8, &dbValue);
+ }
+
+ if ( IsSbA11 () ) {
+ dbValue = 0x09;
+ } else {
+ dbValue = 0x08;
+ }
+ WriteIO (smbusBase + 2, AccWidthUint8, &dbValue);
+ if ( IsSbA11 () ) {
+ dbValue = 0x01;
+ } else {
+ dbValue = 0x10;
+ }
+ WriteIO (smbusBase + 3, AccWidthUint8, &dbValue);
+ dbValue = 0x99;
+ WriteIO (smbusBase + 4, AccWidthUint8, &dbValue);
+ if ( IsSbA11 () ) {
+ dbValue = 0x0f;
+ WriteIO (smbusBase + 0x14, AccWidthUint8, &dbValue);
+ }
+
+ if ( IsSbA12Plus () ) {
+ dbValue = 0x80;
+ WriteIO (smbusBase + 0x14, AccWidthUint8, &dbValue);
+ dbValue = 0x01;
+ WriteIO (smbusBase + 0x17, AccWidthUint8, &dbValue);
+ dbValue = 0x81;
+ WriteIO (smbusBase + 0x14, AccWidthUint8, &dbValue);
+ }
+ //map SB-TSI to tempin0
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + SB_PMIO2_REG92, AccWidthUint8, ~BIT3, BIT3);
+ dbValue = 0x00;
+ WriteIO (smbusBase + 0x16, AccWidthUint8, &dbValue);
+ pConfig->hwm.hwmSbtsiAutoPollStarted = TRUE;
+ } else {
+ hwmSbtsiAutoPollingOff (pConfig);
+ }
+}
+
+/**
+ * hwmSbtsiAutoPollingOff - Hardware Monitor Auto Poll SB-TSI
+ * Off.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmSbtsiAutoPollingOff (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 dbValue;
+ UINT16 smbusBase;
+
+ if ( pConfig->hwm.hwmEnable ) {
+ smbusBase = (UINT16) (pConfig->BuildParameters.Smbus0BaseAddress);
+ dbValue = 0x00;
+ WriteIO (smbusBase + 0x14, AccWidthUint8, &dbValue);
+ hwmSbtsiAutoPollingPause (pConfig);
+ RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG2E, AccWidthUint8, ~(BIT1 + BIT2), 0);
+ RWMEM (ACPI_MMIO_BASE + PMIO2_BASE + SB_PMIO2_REG92, AccWidthUint8, ~BIT3, 0x00);
+ pConfig->hwm.hwmSbtsiAutoPollStarted = FALSE;
+ }
+}
+
+/**
+ * hwmSbtsiAutoPollingPause - Pause Hardware Monitor Auto Poll
+ * SB-TSI Off.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmSbtsiAutoPollingPause (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 dbValue;
+ UINT16 smbusBase;
+
+ if ( pConfig->hwm.hwmEnable && (pConfig->hwm.hwmSbtsiAutoPoll == 1) ) {
+ smbusBase = (UINT16) (pConfig->BuildParameters.Smbus0BaseAddress);
+ dbValue = 0x01;
+ WriteIO (smbusBase + 0x16, AccWidthUint8, &dbValue);
+ dbValue = 0x00;
+ while ( dbValue == 0x00 ) {
+ ReadIO (smbusBase + 0x16, AccWidthUint8, &dbValue);
+ }
+ }
+}
+
+/**
+ * hwmGetRawData - Hardware Monitor Get Raw Data.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmGetRawData (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 i;
+ UINT16 dwValue;
+//_asm { jmp $ };
+ //fan speed
+ for ( i = 0; i < 5 ; i++ ) {
+ ReadPMIO2 (SB_PMIO2_REG69 + i * 5, AccWidthUint16, &dwValue);
+ if ( (dwValue & 0xFFC0) != 0xFFC0 ) {
+ pConfig->hwm.hwmCurrentRaw.fanSpeed[i] = dwValue;
+ } else {
+ pConfig->hwm.hwmCurrentRaw.fanSpeed[i] = 0xFFFF;
+ }
+ }
+ //temperatue
+ for ( i = 0; i < 5 ; i++ ) {
+ ReadPMIO2 (SB_PMIO2_REG95 + i * 4, AccWidthUint16, &dwValue);
+ if ( ( i == 1 ) || (dwValue > 0x4000) ) {
+ pConfig->hwm.hwmCurrentRaw.temperature[i] = dwValue;
+ }
+ }
+ //voltage
+ for ( i = 0; i < 8 ; i++ ) {
+ ReadPMIO2 (SB_PMIO2_REGB8 + i * 4, AccWidthUint16, &dwValue);
+ if ( (dwValue & 0xFFC0) != 0xFFC0 ) {
+ pConfig->hwm.hwmCurrentRaw.voltage[i] = dwValue;
+ }
+ }
+}
+
+/**
+ * hwmCaculate - Hardware Monitor Caculate Raw Data to Display Data.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmCaculate (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 i;
+ UINT16 dwValue;
+ //UINT32 ddValue;
+ //fan speed
+ for ( i = 0; i < 5 ; i++ ) {
+ dwValue = pConfig->hwm.hwmCurrentRaw.fanSpeed[i];
+ if ((dwValue == 0xffff) || (dwValue == 0x0000)) {
+ pConfig->hwm.hwmCurrent.fanSpeed[i] = 0;
+ } else {
+ pConfig->hwm.hwmCurrent.fanSpeed[i] = ( 22720 >> pConfig->hwm.fanSampleFreqDiv ) * 60 / dwValue / 2;
+ }
+ }
+ //temperatue
+ for ( i = 0; i < 5 ; i++ ) {
+ dwValue = pConfig->hwm.hwmCurrentRaw.temperature[i];
+ if ((pConfig->hwm.hwmSbtsiAutoPoll == 1) && (i == 1)) {
+ if ( IsSbA11 () ) {
+ dwValue = (dwValue >> 8) * 10;
+ } else {
+ dwValue = ((dwValue & 0xff00) >> 8) * 10 + (((dwValue & 0x00ff) * 10 ) >> 8);
+ }
+ } else {
+ dwValue = ((dwValue << 3) * pConfig->hwm.hwmTempPar[i].At / pConfig->hwm.hwmCalibrationFactor / 100 - pConfig->hwm.hwmTempPar[i].Ct) / 10 ;
+ }
+ if ( pConfig->hwm.hwmCurrentRaw.temperature[i] == 0 ) {
+ dwValue = 0;
+ }
+ if ( dwValue < 10000 ) {
+ pConfig->hwm.hwmCurrent.temperature[i] = dwValue;
+ } else {
+ pConfig->hwm.hwmCurrent.temperature[i] = 0;
+ }
+ }
+ //voltage
+ for ( i = 0; i < 8 ; i++ ) {
+ dwValue = pConfig->hwm.hwmCurrentRaw.voltage[i];
+ pConfig->hwm.hwmCurrent.voltage[i] = (dwValue >> 6) * 512 / pConfig->hwm.hwmCalibrationFactor;
+ }
+}
+
+/**
+ * hwmGetCalibrationFactor - Hardware Monitor Get Calibration
+ * Factor
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmGetCalibrationFactor (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 dbValue;
+// UINT16 dwValue;
+// UINT32 ddValue;
+ //temperatue parameter
+ ReadPMIO2 (SB_PMIO2_REGEA, AccWidthUint8, &dbValue);
+ if ( dbValue & BIT7 ) {
+ if ( dbValue & BIT6 ) {pConfig->hwm.hwmCalibrationFactor = 0x100 + dbValue;
+ } else {pConfig->hwm.hwmCalibrationFactor = 0x200 + (dbValue & 0x3f ); }
+ } else {
+ pConfig->hwm.hwmCalibrationFactor = 0x200;
+ }
+}
+
+/**
+ * hwmProcessParameter - Hardware Monitor process Parameter
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmProcessParameter (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 i;
+ UINT8 tempChannel;
+ UINT8 dbValue;
+ UINT16 dwValue;
+// UINT32 ddValue;
+ hwmGetCalibrationFactor (pConfig);
+ //temperatue parameter
+ for ( i = 0; i < 5 ; i++ ) {
+ if ( pConfig->hwm.hwmTempPar[i].At == 0 ) {
+ pConfig->hwm.hwmTempPar[i] = tempParDefault[i];
+ }
+ }
+ for ( i = 0; i < 5 ; i++ ) {
+ if ( pConfig->hwm.hwmFanControl[i].LowDuty_reg03 == 100 ) {
+ pConfig->hwm.hwmFanControlCooked[i].LowDuty_reg03 = 255;
+ } else {
+ pConfig->hwm.hwmFanControlCooked[i].LowDuty_reg03 = (pConfig->hwm.hwmFanControl[i].LowDuty_reg03 << 8) / 100;
+ }
+ if ( pConfig->hwm.hwmFanControl[i].MedDuty_reg04 == 100 ) {
+ pConfig->hwm.hwmFanControlCooked[i].MedDuty_reg04 = 255;
+ } else {
+ pConfig->hwm.hwmFanControlCooked[i].MedDuty_reg04 = (pConfig->hwm.hwmFanControl[i].MedDuty_reg04 << 8) / 100;
+ }
+
+ if ( pConfig->hwm.hwmFanControl[i].HighTemp_reg0A > pConfig->hwm.hwmFanControl[i].MedTemp_reg08 ) {
+ dbValue = (UINT8) ((256 - pConfig->hwm.hwmFanControlCooked[i].LowDuty_reg03) / (pConfig->hwm.hwmFanControl[i].HighTemp_reg0A - pConfig->hwm.hwmFanControl[i].MedTemp_reg08));
+ } else {
+ dbValue = (UINT8) ((256 - pConfig->hwm.hwmFanControlCooked[i].LowDuty_reg03));
+ }
+
+ dwValue = pConfig->hwm.hwmFanControl[i].LowTemp_reg06;
+ if (pConfig->hwm.hwmFanControl[i].InputControl_reg00 > 4) {
+ tempChannel = 0;
+ } else {
+ tempChannel = pConfig->hwm.hwmFanControl[i].InputControl_reg00;
+ }
+ if ((pConfig->hwm.hwmSbtsiAutoPoll == 1) && (i == 0)) {
+ dwValue = dwValue << 8;
+ } else {
+ dbValue = (UINT8) (dbValue * 10000 * pConfig->hwm.hwmCalibrationFactor / pConfig->hwm.hwmTempPar[tempChannel].At / 512);
+ dwValue = ((dwValue * 100 + pConfig->hwm.hwmTempPar[tempChannel].Ct ) * 100 * pConfig->hwm.hwmCalibrationFactor / pConfig->hwm.hwmTempPar[tempChannel].At) >> 3;
+ }
+ pConfig->hwm.hwmFanControlCooked[i].LowTemp_reg06 = dwValue;
+ pConfig->hwm.hwmFanControlCooked[i].Multiplier_reg05 = dbValue & 0x3f;
+
+ dwValue = pConfig->hwm.hwmFanControl[i].MedTemp_reg08;
+ if ((pConfig->hwm.hwmSbtsiAutoPoll == 1) && (i == 0)) {
+ dwValue = dwValue << 8;
+ } else {
+ dwValue = ((dwValue * 100 + pConfig->hwm.hwmTempPar[tempChannel].Ct ) * 100 * pConfig->hwm.hwmCalibrationFactor / pConfig->hwm.hwmTempPar[tempChannel].At) >> 3;
+ }
+ pConfig->hwm.hwmFanControlCooked[i].MedTemp_reg08 = dwValue;
+ dwValue = pConfig->hwm.hwmFanControl[i].HighTemp_reg0A;
+ if ((pConfig->hwm.hwmSbtsiAutoPoll == 1) && (i == 0)) {
+ dwValue = dwValue << 8;
+ } else {
+ dwValue = ((dwValue * 100 + pConfig->hwm.hwmTempPar[tempChannel].Ct ) * 100 * pConfig->hwm.hwmCalibrationFactor / pConfig->hwm.hwmTempPar[tempChannel].At) >> 3;
+ }
+ pConfig->hwm.hwmFanControlCooked[i].HighTemp_reg0A = dwValue;
+ }
+}
+
+/**
+ * hwmSetRegister - Hardware Monitor Set Parameter
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmSetRegister (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 *pDbValue;
+ UINT8 i;
+ UINT8 registerN;
+ UINT8 registerPM2RegF8;
+ UINT8 registerPM2RegF9;
+
+ //UINT16 dwValue;
+// UINT32 ddValue;
+ //Configure Fans
+ for ( i = 0; i < 5 ; i++ ) {
+ pDbValue = &(pConfig->hwm.hwmFanControlCooked[i].InputControl_reg00);
+ for ( registerN = 0; registerN < 0x0E ; registerN++ ) {
+ WritePMIO2 (i * 0x10 + registerN, AccWidthUint8, pDbValue);
+ pDbValue ++;
+ }
+ }
+ //Configure Sample Frequency Divider
+ WritePMIO2 (SB_PMIO2_REG63, AccWidthUint8, &(pConfig->hwm.fanSampleFreqDiv));
+
+ //Configure Mode
+ ReadPMIO2 (0xF8, AccWidthUint8, &registerPM2RegF8);
+ ReadPMIO2 (0xF9, AccWidthUint8, &registerPM2RegF9);
+ for ( i = 0; i < 5 ; i++ ) {
+ if (pConfig->hwm.hwmTempPar[i].Mode == BIT0) {
+ registerPM2RegF8 |= 1 << (i + 3);
+ } else if (pConfig->hwm.hwmTempPar[i].Mode == BIT1) {
+ registerPM2RegF9 |= 1 << (i + 3);
+ }
+ }
+ WritePMIO2 (0xF8, AccWidthUint8, &registerPM2RegF8);
+ WritePMIO2 (0xF9, AccWidthUint8, &registerPM2RegF9);
+}
+
+/**
+ * hwmUpdateData - Hardware Monitor Update Data.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmUpdateData (
+ IN AMDSBCFG* pConfig
+ )
+{
+ if ( pConfig->hwm.hwmEnable ) {
+ hwmSbtsiAutoPolling (pConfig);
+ hwmGetRawData (pConfig);
+ hwmCaculate (pConfig);
+ }
+}
+
+/**
+ * hwmCopyFanControl - Hardware Monitor Copy Fan Control Data.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmCopyFanControl (
+ IN AMDSBCFG* pConfig
+ )
+{
+ UINT8 *fanControl;
+ UINT8 *fanControlCooked;
+ if ( pConfig->hwm.hwmEnable ) {
+ fanControl = & pConfig->hwm.hwmFanControl[0].InputControl_reg00;
+ fanControlCooked = & pConfig->hwm.hwmFanControlCooked[0].InputControl_reg00;
+ MemoryCopy (fanControlCooked, fanControl, (sizeof (HWM_fan_ctl_struct) * 5));
+ }
+}
+/**
+ * hwmInit - Init Hardware Monitor.
+ *
+ *
+ * @param[in] pConfig Southbridge configuration structure pointer.
+ *
+ */
+VOID
+hwmInit (
+ IN AMDSBCFG* pConfig
+ )
+{
+ hwmInitRegister (pConfig);
+ if ( pConfig->hwm.hwmEnable ) {
+ hwmCopyFanControl (pConfig);
+ hwmProcessParameter (pConfig);
+ hwmSetRegister (pConfig);
+ hwmSbtsiAutoPolling (pConfig);
+ }
+}
+
+//#endif