blob: 217f731f8b58d8b4ecc442ad1d2a13ea563e60ab [file] [log] [blame]
/* $NoKeywords:$ */
/**
* @file
*
* Config FCH Hwm controller
*
* Init Hwm Controller features.
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: FCH
* @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 2010) $
*
*/
/*
*****************************************************************************
*
* 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 "FchPlatform.h"
#include "Filecode.h"
#define FILECODE PROC_FCH_HWM_FAMILY_HUDSON2_HUDSON2HWMENVSERVICE_FILECODE
FCH_HWM_TEMP_PAR TempParDefault[] = {
{ 5220, 27365 , 0 },
{ 5225, 27435 , 0 },
{ 5220, 27516 , BIT0 }, ///High Ratio
{ 5212, 27580 , BIT1 }, ///High Current
{ 5123, 27866 , 0 }
};
/**
* HwmInitRegister - Init Hardware Monitor Register.
*
*
* @param[in] FchDataPtr Fch configuration structure pointer.
*
*/
VOID
HwmInitRegister (
IN VOID *FchDataPtr
)
{
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xB2, AccessWidth8, 0, 0x55);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xB3, AccessWidth8, 0, 0x55);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x91, AccessWidth8, 0, 0x55);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x92, AccessWidth8, 0, 0x55);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x00, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x10, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x20, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x30, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x40, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x66, AccessWidth8, 0, 0x01);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x6B, AccessWidth8, 0, 0x01);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x70, AccessWidth8, 0, 0x01);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x75, AccessWidth8, 0, 0x01);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0x7A, AccessWidth8, 0, 0x01);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xE6, AccessWidth8, 0xff, 0x02);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xF8, AccessWidth8, 0, 0x05);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xF9, AccessWidth8, 0, 0x06);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xFF, AccessWidth8, 0, 0x42);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xE9, AccessWidth8, 0, 0xFF);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xEB, AccessWidth8, 0, 0x1F);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xEF, AccessWidth8, 0, 0x04);
RwMem (ACPI_MMIO_BASE + PMIO2_BASE + 0xFB, AccessWidth8, 0, 0x00);
//2.9 Enhancement of FanOut0 Control
RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG50, AccessWidth32, ~ (BIT11 + BIT20), (BIT11 + BIT20));
RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGB6, AccessWidth8, 0x0F, 0x10);
}
/**
* HwmProcessParameter - Hardware Monitor process Parameter
*
*
* @param[in] FchDataPtr Fch configuration structure pointer.
*
*/
VOID
HwmProcessParameter (
IN VOID *FchDataPtr
)
{
UINT8 Index;
UINT8 TempChannel;
UINT8 ValueByte;
UINT16 ValueWord;
FCH_DATA_BLOCK *LocalCfgPtr;
LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
HwmGetCalibrationFactor (LocalCfgPtr);
//
//temperatue parameter
//
for ( Index = 0; Index < 5 ; Index++ ) {
if ( LocalCfgPtr->Hwm.HwmTempPar[Index].At == 0 ) {
LocalCfgPtr->Hwm.HwmTempPar[Index] = TempParDefault[Index];
}
}
for ( Index = 0; Index < 5 ; Index++ ) {
if ( LocalCfgPtr->Hwm.HwmFanControl[Index].LowDutyReg03 == 100 ) {
LocalCfgPtr->Hwm.HwmFanControl[Index].LowDutyReg03 = 255;
} else {
LocalCfgPtr->Hwm.HwmFanControl[Index].LowDutyReg03 = (LocalCfgPtr->Hwm.HwmFanControl[Index].LowDutyReg03 << 8) / 100;
}
if ( LocalCfgPtr->Hwm.HwmFanControl[Index].MedDutyReg04 == 100 ) {
LocalCfgPtr->Hwm.HwmFanControl[Index].MedDutyReg04 = 255;
} else {
LocalCfgPtr->Hwm.HwmFanControl[Index].MedDutyReg04 = (LocalCfgPtr->Hwm.HwmFanControl[Index].MedDutyReg04 << 8) / 100;
}
ValueByte = (UINT8) ((256 - LocalCfgPtr->Hwm.HwmFanControl[Index].LowDutyReg03) / (LocalCfgPtr->Hwm.HwmFanControl[Index].HighTempReg0A - LocalCfgPtr->Hwm.HwmFanControl[Index].MedTempReg08));
ValueWord = LocalCfgPtr->Hwm.HwmFanControl[Index].LowTempReg06;
if (LocalCfgPtr->Hwm.HwmFanControl[Index].InputControlReg00 > 4) {
TempChannel = 0;
} else {
TempChannel = LocalCfgPtr->Hwm.HwmFanControl[Index].InputControlReg00;
}
if ((LocalCfgPtr->Hwm.HwmFchtsiAutoPoll == 1) && (Index == 0)) {
ValueWord = ValueWord << 8;
} else {
ValueByte = (UINT8) (ValueByte * 10000 / LocalCfgPtr->Hwm.HwmTempPar[TempChannel].At);
ValueWord = ((ValueWord * 100 + LocalCfgPtr->Hwm.HwmTempPar[TempChannel].Ct ) * 100 * LocalCfgPtr->Hwm.HwmCalibrationFactor / LocalCfgPtr->Hwm.HwmTempPar[TempChannel].At) >> 3;
}
LocalCfgPtr->Hwm.HwmFanControl[Index].LowTempReg06 = ValueWord;
LocalCfgPtr->Hwm.HwmFanControl[Index].MultiplierReg05 = ValueByte & 0x3f;
ValueWord = LocalCfgPtr->Hwm.HwmFanControl[Index].MedTempReg08;
if ((LocalCfgPtr->Hwm.HwmFchtsiAutoPoll == 1) && (Index == 0)) {
ValueWord = ValueWord << 8;
} else {
ValueWord = ((ValueWord * 100 + LocalCfgPtr->Hwm.HwmTempPar[TempChannel].Ct ) * 100 * LocalCfgPtr->Hwm.HwmCalibrationFactor / LocalCfgPtr->Hwm.HwmTempPar[TempChannel].At) >> 3;
}
LocalCfgPtr->Hwm.HwmFanControl[Index].MedTempReg08 = ValueWord;
ValueWord = LocalCfgPtr->Hwm.HwmFanControl[Index].HighTempReg0A;
if ((LocalCfgPtr->Hwm.HwmFchtsiAutoPoll == 1) && (Index == 0)) {
ValueWord = ValueWord << 8;
} else {
ValueWord = ((ValueWord * 100 + LocalCfgPtr->Hwm.HwmTempPar[TempChannel].Ct ) * 100 * LocalCfgPtr->Hwm.HwmCalibrationFactor / LocalCfgPtr->Hwm.HwmTempPar[TempChannel].At) >> 3;
}
LocalCfgPtr->Hwm.HwmFanControl[Index].HighTempReg0A = ValueWord;
}
}
/**
* hwmSetRegister - Hardware Monitor Set Parameter
*
*
* @param[in] FchDataPtr Fch configuration structure pointer.
*
*/
VOID
HwmSetRegister (
IN VOID *FchDataPtr
)
{
UINT8 *DbValuePtr;
UINT8 Index;
UINT8 RegisterN;
UINT8 RegisterPM2RegF8;
UINT8 RegisterPM2RegF9;
FCH_DATA_BLOCK *LocalCfgPtr;
AMD_CONFIG_PARAMS *StdHeader;
LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
StdHeader = LocalCfgPtr->StdHeader;
//
//Configure Fans
//
for ( Index = 0; Index < 5 ; Index++ ) {
DbValuePtr = &(LocalCfgPtr->Hwm.HwmFanControl[Index].InputControlReg00);
for ( RegisterN = 0; RegisterN < 0x0E ; RegisterN++ ) {
WritePmio2 (Index * 0x10 + RegisterN, AccessWidth8, DbValuePtr, StdHeader);
DbValuePtr ++;
}
}
//
//Configure Sample Frequency Divider
//
WritePmio2 (FCH_PMIO2_REG63, AccessWidth8, &(LocalCfgPtr->Hwm.FanSampleFreqDiv), StdHeader);
//
//Configure Mode
//
ReadPmio2 (0xF8, AccessWidth8, &RegisterPM2RegF8, StdHeader);
ReadPmio2 (0xF9, AccessWidth8, &RegisterPM2RegF9, StdHeader);
for ( Index = 0; Index < 5 ; Index++ ) {
if (LocalCfgPtr->Hwm.HwmTempPar[Index].Mode == BIT0) {
RegisterPM2RegF8 |= 1 << (Index + 3);
} else if (LocalCfgPtr->Hwm.HwmTempPar[Index].Mode == BIT1) {
RegisterPM2RegF9 |= 1 << (Index + 3);
}
}
WritePmio2 (0xF8, AccessWidth8, &RegisterPM2RegF8, StdHeader);
WritePmio2 (0xF9, AccessWidth8, &RegisterPM2RegF9, StdHeader);
}
/**
* hwmGetCalibrationFactor - Hardware Monitor Get Calibration
* Factor
*
*
* @param[in] FchDataPtr Fch configuration structure pointer.
*
*/
VOID
HwmGetCalibrationFactor (
IN VOID *FchDataPtr
)
{
UINT8 ValueByte;
FCH_DATA_BLOCK *LocalCfgPtr;
AMD_CONFIG_PARAMS *StdHeader;
LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
StdHeader = LocalCfgPtr->StdHeader;
//
//temperatue parameter
//
ReadPmio2 (FCH_PMIO2_REGEA, AccessWidth8, &ValueByte, StdHeader);
if ( ValueByte & BIT7 ) {
if ( ValueByte & BIT6 ) {
LocalCfgPtr->Hwm.HwmCalibrationFactor = 0x100 + ValueByte;
} else {
LocalCfgPtr->Hwm.HwmCalibrationFactor = 0x200 + (ValueByte & 0x3f );
}
} else {
LocalCfgPtr->Hwm.HwmCalibrationFactor = 0x200;
}
}