diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR')
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr2.c | 274 | ||||
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr3.c | 429 | ||||
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/maudr3.c | 260 |
3 files changed, 963 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr2.c b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr2.c new file mode 100644 index 0000000000..6f2249b5af --- /dev/null +++ b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr2.c @@ -0,0 +1,274 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mardr2.c + * + * Platform specific settings for DR DDR2 L1 system + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ardk) + * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 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. + * + * *************************************************************************** + * + */ + +/* This file contains routine that add platform specific support L1 */ + + +#include "AGESA.h" +#include "mport.h" +#include "ma.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_ARDK_DR_MARDR2_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +STATIC CONST UINT8 ROMDATA DrRDdr2CLKDis[] = {0x00, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x00}; + +// Chip select 0, 1, 4, 5 maps to M[B,A]_CKE[0] +// Chip select 2, 3, 6, 7 maps to M[B,A]_CKE[1] +STATIC CONST UINT8 ROMDATA DrRDdr2CKETri[] = {0x33, 0xCC}; + +// 2 dimms per channel +// Dimm 0: BP_MEMODTx[2,0] +// Dimm 1: BP_MEMODTx[3,1] +STATIC CONST UINT8 ROMDATA DrRDdr2ODTTri2D[] = {0x03, 0x0C, 0x32, 0xC8}; +// 3 dimms per channel +// Dimm 0: BP_MEMODTx[0] +// Dimm 1: BP_MEMODTx[3,1] +// Dimm 2: BP_MEMODTx[2] +STATIC CONST UINT8 ROMDATA DrRDdr2ODTTri3D[] = {0x03, 0x0C, 0x30, 0xC8}; +// 4 dimms per channel +// Dimm 0: BP_MEMODTx[0] +// Dimm 1: BP_MEMODTx[1] +// Dimm 2: BP_MEMODTx[2] +// Dimm 3: BP_MEMODTx[3] +STATIC CONST UINT8 ROMDATA DrRDdr2ODTTri4D[] = {0x03, 0x0C, 0x30, 0xC0}; + +// BIOS must not tri-state chip select pin corresponding to the second chip +// select of a single rank registered dimm +STATIC CONST UINT8 ROMDATA DrRDdr2CSTri[] = {0x01, 0x03, 0x04, 0x0C, 0x10, 0x30, 0x40, 0xC0}; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This is function sets the platform specific settings for DR DDR2 L1 system + * + * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE + * @param[in] SocketID Socket number + * @param[in,out] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return AGESA_SUCCESS + * @return CurrentChannel->MemClkDisMap Points this pointer to RB MemClkDis table + * @return CurrentChannel->ChipSelTriMap Points this pointer to RB CS table + * @return CurrentChannel->CKETriMap Points this pointer to RB ODT table + * @return CurrentChannel->ODTTriMap Points this pointer to RB CKE table + * @return CurrentChannel->DctEccDQSLike Indicates the bytes that should be averaged for ECC + * @return CurrentChannel->DctEccDQSScale Indicates the scale that should be used for Averaging ECC byte + * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel + * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel + * @return CurrentChannel->SlowMode Slow Mode + * + */ + +AGESA_STATUS +MemAGetPsCfgRDr2 ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ) +{ + STATIC CONST ADV_PSCFG_ENTRY PSCfg4D[] = { + {ANY_, ANY_, 0x00000000, 0x00111222, 1}, + {ANY_, ANY_, 0x00370000, 0x00111222, 2} + }; + + STATIC CONST ADV_PSCFG_ENTRY PSCfg8D[] = { + {ANY_, ANY_, 0x00000000, 0x00111222, 1}, + {ANY_, ANY_, 0x00370000, 0x00111222, 2}, + {ANY_, ANY_, 0x002F0000, 0x00111222, ANY_} + }; + + CONST ADV_PSCFG_ENTRY *PSCfgPtr; + UINT16 i; + UINT8 MaxDimmPerCH; + UINT16 TabSize; + UINT8 Loads; + UINT8 Dimms; + UINT16 Speed; + UINT32 AddrTmgCTL; + UINT32 DctOdcCtl; + UINT16 QRPresent; + UINT16 DRx4Present; + BOOLEAN SlowMode; + UINT8 *DimmsPerChPtr; + + ASSERT (MemData != 0); + ASSERT (CurrentChannel != 0); + + if ((CurrentChannel->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->TechType != DDR2_TECHNOLOGY) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->RegDimmPresent != CurrentChannel->ChDimmValid) { + return AGESA_UNSUPPORTED; + } + + // Prepare inputs + Loads = CurrentChannel->Loads; + Dimms = CurrentChannel->Dimms; + Speed = CurrentChannel->DCTPtr->Timings.Speed; + DimmsPerChPtr = FindPSOverrideEntry (MemData->ParameterListPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, SocketID, CurrentChannel->ChannelID); + if (DimmsPerChPtr != NULL) { + MaxDimmPerCH = *DimmsPerChPtr; + } else { + MaxDimmPerCH = 2; + } + QRPresent = CurrentChannel->DimmQrPresent; + DRx4Present = CurrentChannel->DimmDrPresent & CurrentChannel->Dimmx4Present; + if (QRPresent) { + Dimms = (Dimms + 1) / 2; + } + + // Table look up + if (MaxDimmPerCH <= 2) { + PSCfgPtr = PSCfg4D; + TabSize = GET_SIZE_OF (PSCfg4D); + } else { + PSCfgPtr = PSCfg8D; + TabSize = GET_SIZE_OF (PSCfg8D); + } + DctOdcCtl = 0; + AddrTmgCTL = 0; + for (i = 0; i < TabSize; i++) { + if ((PSCfgPtr[i].Dimms == ANY_) || (PSCfgPtr[i].Dimms == Dimms)) { + if ((PSCfgPtr[i].Speed == ANY_) || (PSCfgPtr[i].Speed == Speed)) { + if ((PSCfgPtr[i].Loads == ANY_) || (PSCfgPtr[i].Loads >= Loads)) { + AddrTmgCTL = PSCfgPtr[i].AddrTmg; + DctOdcCtl = PSCfgPtr[i].Odc; + break; + } + } + } + } + ASSERT (i == TabSize); + SlowMode = FALSE; // 1T + + // + // Overrides and/or exceptions + // + + if (QRPresent == 0x55) { + // QR for 4DIMM case only + AddrTmgCTL = 0x002F0000; + if (Speed >= DDR667_FREQUENCY) { + DctOdcCtl = 0x00331222; + } + } + + if (Speed >= DDR667_FREQUENCY) { + if ((QRPresent != 0) || (DRx4Present != 0)) { + AddrTmgCTL |= 0x00002F00; + } + if (Dimms >= 3) { + AddrTmgCTL |= 0x0000002F; + } + if (Dimms == 3 || Dimms == 4) { + DctOdcCtl = 0x00331222; + } + } + + // Adjust Processor ODT + if (Dimms == 1) { + DctOdcCtl |= 0x20000000; // 75ohms + } else { + DctOdcCtl |= 0x10000000; // 150ohms + } + + CurrentChannel->MemClkDisMap = (UINT8 *) DrRDdr2CLKDis; + CurrentChannel->CKETriMap = (UINT8 *) DrRDdr2CKETri; + CurrentChannel->ChipSelTriMap = (UINT8 *) DrRDdr2CSTri; + + switch (MaxDimmPerCH) { + case 3: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr2ODTTri3D; + break; + case 4: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr2ODTTri4D; + break; + default: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr2ODTTri2D; + } + + CurrentChannel->DctEccDqsLike = 0x0504; + CurrentChannel->DctEccDqsScale = 0; + CurrentChannel->DctAddrTmg = AddrTmgCTL; + CurrentChannel->DctOdcCtl = DctOdcCtl; + CurrentChannel->SlowMode = SlowMode; + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr3.c b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr3.c new file mode 100644 index 0000000000..5335b49835 --- /dev/null +++ b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/mardr3.c @@ -0,0 +1,429 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mardr3.c + * + * Memory Controller, registered dimms + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ardk) + * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 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. + * + * *************************************************************************** + * + */ + +/* This file contains routine that add platform specific support AM3 */ + + +#include "AGESA.h" +#include "ma.h" +#include "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "mu.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_ARDK_DR_MARDR3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +STATIC CONST UINT8 ROMDATA DrRDdr3CLKDis[] = {0x00, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x00}; + +// Even chip select maps to M[B,A]_CKE[0] +// Odd chip select maps to M[B,A]_CKE[1] +STATIC CONST UINT8 ROMDATA DrRDdr3CKETri[] = {0x55, 0xAA}; + +// 2 dimms per channel +// Dimm 0: BP_MEMODTx[2,0] +// Dimm 1: BP_MEMODTx[3,1] +STATIC CONST UINT8 ROMDATA DrRDdr3ODTTri2D[] = {0x03, 0x0C, 0x32, 0xC8}; +// 3 dimms per channel +// Dimm 0: BP_MEMODTx[0] +// Dimm 1: BP_MEMODTx[3,1] +// Dimm 2: BP_MEMODTx[2] +STATIC CONST UINT8 ROMDATA DrRDdr3ODTTri3D[] = {0x03, 0x0C, 0x30, 0xC8}; +// 4 dimms per channel +// Dimm 0: BP_MEMODTx[0] +// Dimm 1: BP_MEMODTx[1] +// Dimm 2: BP_MEMODTx[2] +// Dimm 3: BP_MEMODTx[3] +STATIC CONST UINT8 ROMDATA DrRDdr3ODTTri4D[] = {0x03, 0x0C, 0x30, 0xC0}; + +// BIOS must not tri-state chip select pin corresponding to the second chip +// select of a single rank registered dimm +STATIC CONST UINT8 ROMDATA DrRDdr3CSTri[] = {0x01, 0x03, 0x04, 0x0C, 0x10, 0x30, 0x40, 0xC0}; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This is function sets the platform specific settings for DR DDR3 L1 system + * + * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE + * @param[in] SocketID Socket number + * @param[in,out] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return AGESA_SUCCESS + * @return CurrentChannel->MemClkDisMap Points this pointer to RB MemClkDis table + * @return CurrentChannel->ChipSelTriMap Points this pointer to RB CS table + * @return CurrentChannel->CKETriMap Points this pointer to RB ODT table + * @return CurrentChannel->ODTTriMap Points this pointer to RB CKE table + * @return CurrentChannel->DctEccDQSLike Indicates the bytes that should be averaged for ECC + * @return CurrentChannel->DctEccDQSScale Indicates the scale that should be used for Averaging ECC byte + * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel + * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel + * @return CurrentChannel->SlowMode Slow Mode + * + * + */ + +AGESA_STATUS +MemAGetPsCfgRDr3 ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ) +{ + STATIC CONST ADV_R_PSCFG_ENTRY PSCfg2DIMMs[] = { + {DDR800_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, \ + 0x00000000, 0x0000, 1}, + {DDR800_FREQUENCY, QR_DIMM0 + QR_DIMM1, \ + 0x00000000, 0x0040, 1}, + {DDR800_FREQUENCY, ANY_DIMM0 + ANY_DIMM1, \ + 0x00000000, 0x4004, 2}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, \ + 0x003C3C3C, 0x0000,1}, + {DDR1066_FREQUENCY, QR_DIMM0 + QR_DIMM1, \ + 0x003C3C3C, 0x0040, 1}, + {DDR1066_FREQUENCY, ANY_DIMM0 + ANY_DIMM1, \ + 0x003A3C3A, 0x4004, 2}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, \ + 0x003A3A3A, 0x0000, 1}, + {DDR1333_FREQUENCY, QR_DIMM0 + QR_DIMM1, \ + 0x003A3A3A, 0x0040, 1}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, \ + 0x00383A38, 0x4040, 2}, + {DDR1333_FREQUENCY, QR_DIMM0 + QR_DIMM1, \ + 0x00383A38, 0x4004, 2}, + {DDR1600_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, \ + 0x00373937, 0x0000, 1}, + {DDR1600_FREQUENCY, QR_DIMM0 + QR_DIMM1, \ + 0x00373937, 0x0040, 1}, + {DDR1600_FREQUENCY, ANY_DIMM0 + ANY_DIMM1, \ + 0x00353935, 0x4004, 2} + }; + + STATIC CONST ADV_R_PSCFG_ENTRY PSCfg3DIMMs[] = { + {DDR800_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00000000, 0x0000, 1}, + {DDR800_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00000000, 0x4040, 2}, + {DDR800_FREQUENCY, SR_DIMM0 + DR_DIMM0 + ANY_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00380038, 0x4004, 3}, + {DDR800_FREQUENCY, QR_DIMM1, \ + 0x00000000, 0x0040, 1}, + {DDR800_FREQUENCY, SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00000000, 0x4004, 2}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x003C3C3C, 0x0000, 1}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x003A3C3A, 0x4040, 2}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00373C37, 0x4040, 3}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00373C37, 0x4004, 3}, + {DDR1066_FREQUENCY, QR_DIMM1, \ + 0x003C3C3C, 0x0040, 1}, + {DDR1066_FREQUENCY, SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x003A3C3A, 0x4004, 2}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x003A3A3A, 0x0000, 1}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00383A38, 0x4040, 2}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + ANY_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00343A34, 0x4004, 3}, + {DDR1333_FREQUENCY, QR_DIMM1, \ + 0x003A3A3A, 0x0040, 1}, + {DDR1333_FREQUENCY, SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00383A38, 0x4004, 2}, + {DDR1600_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00393939, 0x0000, 1}, + {DDR1600_FREQUENCY, SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00363936, 0x4040, 2}, + {DDR1600_FREQUENCY, SR_DIMM0 + DR_DIMM0 + ANY_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00303930, 0x4004, 3}, + {DDR1600_FREQUENCY, QR_DIMM1, \ + 0x00393939, 0x0040, 1}, + {DDR1600_FREQUENCY, SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, \ + 0x00363936, 0x4004, 2} + }; + + STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY PSCfg2DIMMsWlODT[] = { + {SR_DIMM0, {0x01, 0x00, 0x00, 0x00}, 1}, + {DR_DIMM0, {0x04, 0x00, 0x00, 0x00}, 1}, + {SR_DIMM1, {0x00, 0x02, 0x00, 0x00}, 1}, + {DR_DIMM1, {0x00, 0x08, 0x00, 0x00}, 1}, + {QR_DIMM1, {0x00, 0x0A, 0x00, 0x00}, 1}, + {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, {0x03, 0x03, 0x00, 0x00}, 2}, + {SR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2}, + {DR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2}, + {QR_DIMM0 + SR_DIMM1, {0x03, 0x07, 0x06, 0x00}, 2}, + {QR_DIMM0 + DR_DIMM1, {0x03, 0x07, 0x06, 0x00}, 2}, + {QR_DIMM0 + QR_DIMM1, {0x0B, 0x07, 0x0E, 0x0D}, 2} + }; + + STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY PSCfg3DIMMsWlODT[] = { + {SR_DIMM2 + DR_DIMM2, {0x00, 0x00, 0x04, 0x00}, 1}, + {SR_DIMM0 + DR_DIMM0, {0x01, 0x02, 0x00, 0x00}, 1}, + {SR_DIMM0 + DR_DIMM0 + SR_DIMM2 + DR_DIMM2, {0x05, 0x00, 0x05, 0x00}, 2}, + {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x07, 0x07, 0x07, 0x00}, 3}, + {QR_DIMM1, {0x00, 0x0A, 0x00, 0x0A}, 1}, + {QR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x00, 0x06, 0x0E, 0x0C}, 2}, + {SR_DIMM0 + DR_DIMM0 + QR_DIMM1, {0x0B, 0x03, 0x00, 0x09}, 2}, + {SR_DIMM0 + DR_DIMM0 + QR_DIMM1 + SR_DIMM2 + DR_DIMM2, {0x0F, 0x07, 0x0F, 0x0D}, 3} + }; + + STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY PSCfg4DIMMsWlODT[] = { + {ANY_DIMM3, {0x00, 0x00, 0x00, 0x08}, 1}, + {ANY_DIMM2 + ANY_DIMM3, {0x00, 0x00, 0x0C, 0x0C}, 2}, + {ANY_DIMM1 + ANY_DIMM2 + ANY_DIMM3, {0x00, 0x0E, 0x0E, 0x0E}, 3}, + {ANY_DIMM0 + ANY_DIMM1 + ANY_DIMM2 + ANY_DIMM3, {0x0F, 0x0F, 0x0F, 0x0F}, 4} + }; + UINT16 i; + UINT16 j; + UINT8 MaxDimmPerCH; + UINT8 Dimms; + UINT16 Speed; + UINT16 DIMMRankType; + UINT16 _DIMMRankType; + UINT8 DimmTpMatch; + UINT32 AddrTmgCTL; + UINT32 DctOdcCtl; + UINT16 RC2RC8; + BOOLEAN SlowMode; + UINT8 PSCfgSize; + UINT8 PSCfgWlODTSize; + UINT8 PhyWLODT[4]; + CONST ADV_R_PSCFG_ENTRY *PSCfgPtr; + CONST ADV_R_PSCFG_WL_ODT_ENTRY *PSCfgWlODTPtr; + UINT8 *DimmsPerChPtr; + + AddrTmgCTL = 0; + DctOdcCtl = 0; + RC2RC8 = 0; + SlowMode = FALSE; + ASSERT (MemData != NULL); + PhyWLODT[0] = 0x0F; + PhyWLODT[1] = 0x0F; + PhyWLODT[2] = 0x0F; + PhyWLODT[3] = 0x0F; + if ((CurrentChannel->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->TechType != DDR3_TECHNOLOGY) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->RegDimmPresent != CurrentChannel->ChDimmValid) { + return AGESA_UNSUPPORTED; + } + // Prepare inputs + Dimms = CurrentChannel->Dimms; + Speed = CurrentChannel->DCTPtr->Timings.Speed; + + DimmsPerChPtr = FindPSOverrideEntry (MemData->ParameterListPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, SocketID, CurrentChannel->ChannelID); + if (DimmsPerChPtr != NULL) { + MaxDimmPerCH = *DimmsPerChPtr; + } else { + MaxDimmPerCH = 2; + } + + DIMMRankType = MemAGetPsRankType (CurrentChannel); + + if (MaxDimmPerCH == 4) { + PSCfgPtr = NULL; + PSCfgSize = NULL; + PSCfgWlODTPtr = PSCfg4DIMMsWlODT; + PSCfgWlODTSize = sizeof (PSCfg4DIMMsWlODT) / sizeof (ADV_R_PSCFG_WL_ODT_ENTRY); + } else if (MaxDimmPerCH == 3) { + PSCfgPtr = PSCfg3DIMMs; + PSCfgSize = sizeof (PSCfg3DIMMs) / sizeof (ADV_R_PSCFG_ENTRY); + PSCfgWlODTPtr = PSCfg3DIMMsWlODT; + PSCfgWlODTSize = sizeof (PSCfg3DIMMsWlODT) / sizeof (ADV_R_PSCFG_WL_ODT_ENTRY); + } else { + PSCfgPtr = PSCfg2DIMMs; + PSCfgSize = sizeof (PSCfg2DIMMs) / sizeof (ADV_R_PSCFG_ENTRY); + PSCfgWlODTPtr = PSCfg2DIMMsWlODT; + PSCfgWlODTSize = sizeof (PSCfg2DIMMsWlODT) / sizeof (ADV_R_PSCFG_WL_ODT_ENTRY); + } + + // AddrTmgCTL and DctOdcCtl + if (MaxDimmPerCH != 4) { + for (i = 0; i < PSCfgSize; i++, PSCfgPtr++) { + if ((Speed != PSCfgPtr->Speed) || (Dimms != PSCfgPtr->Dimms)) { + continue; + } + DimmTpMatch = 0; + _DIMMRankType = DIMMRankType & PSCfgPtr->DIMMRankType; + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + if ((_DIMMRankType & (UINT16) 0x0F << (j << 2)) != 0) { + DimmTpMatch++; + } + } + if (DimmTpMatch == PSCfgPtr->Dimms) { + AddrTmgCTL = PSCfgPtr->AddrTmg; + DctOdcCtl = 0x00223222; + RC2RC8 = PSCfgPtr->RC2RC8; + break; + } + } + } + + // + // Overrides and/or exceptions + // + DimmTpMatch = 0; + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + if ((DIMMRankType & (UINT16) 0x03 << (j << 2)) != 0) { + DimmTpMatch++; + } + } + if (MaxDimmPerCH == 4) { + if (DimmTpMatch > 0) { + DctOdcCtl = 0x00223222; + if ((Speed == DDR800_FREQUENCY) && (DimmTpMatch == 1)) { + DctOdcCtl = 0x00113222; + } + } + if (DimmTpMatch >= 3) { + AddrTmgCTL |= 0x002F0000; + } + if (DimmTpMatch >= 2) { + RC2RC8 = 0x4040; + } + } else { + if ((Dimms == 1) && (DimmTpMatch == 1)) { + DctOdcCtl = 0x00113222; + } + } + + //RC2 and RC8 + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + // CtrlWrd02(s) will contain the info. of SPD byte 63 after MemTDIMMPresence3 execution. + if (CurrentChannel->CtrlWrd02[j] > 0) { + if (CurrentChannel->CtrlWrd02[j] == 1) { + // Store real RC2 and RC8 value (High byte) into CtrlWrd02(s) and CtrlWrd08(s). + CurrentChannel->CtrlWrd02[j] = (UINT8) (RC2RC8 >> 12) & 0x000F; + CurrentChannel->CtrlWrd08[j] = (UINT8) (RC2RC8 >> 8) & 0x000F; + } else { + // Store real RC2 and RC8 value (low byte) into CtrlWrd02(s) and CtrlWrd08(s). + CurrentChannel->CtrlWrd02[j] = (UINT8) (RC2RC8 >> 4) & 0x000F; + CurrentChannel->CtrlWrd08[j] = (UINT8) RC2RC8 & 0x000F; + } + } + } + + + //WLODT + for (i = 0; i < PSCfgWlODTSize; i++, PSCfgWlODTPtr++) { + if (Dimms != PSCfgWlODTPtr->Dimms) { + continue; + } + DimmTpMatch = 0; + _DIMMRankType = DIMMRankType & PSCfgWlODTPtr->DIMMRankType; + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + if ((_DIMMRankType & (UINT16) 0x0F << (j << 2)) != 0) { + DimmTpMatch++; + } + } + if (DimmTpMatch == PSCfgWlODTPtr->Dimms) { + PhyWLODT[0] = PSCfgWlODTPtr->PhyWrLvOdt[0]; + PhyWLODT[1] = PSCfgWlODTPtr->PhyWrLvOdt[1]; + PhyWLODT[2] = PSCfgWlODTPtr->PhyWrLvOdt[2]; + PhyWLODT[3] = PSCfgWlODTPtr->PhyWrLvOdt[3]; + break; + } + } + + // Set ProcODT + DctOdcCtl |= 0x20000000; + + CurrentChannel->MemClkDisMap = (UINT8 *) DrRDdr3CLKDis; + CurrentChannel->CKETriMap = (UINT8 *) DrRDdr3CKETri; + CurrentChannel->ChipSelTriMap = (UINT8 *) DrRDdr3CSTri; + + switch (MaxDimmPerCH) { + case 3: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr3ODTTri3D; + break; + case 4: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr3ODTTri4D; + break; + default: + CurrentChannel->ODTTriMap = (UINT8 *) DrRDdr3ODTTri2D; + } + + CurrentChannel->DctAddrTmg = AddrTmgCTL; + CurrentChannel->DctOdcCtl = DctOdcCtl; + for (i = 0; i < sizeof (CurrentChannel->PhyWLODT); i++) { + CurrentChannel->PhyWLODT[i] = PhyWLODT[i]; + } + CurrentChannel->SlowMode = SlowMode; + + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/maudr3.c b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/maudr3.c new file mode 100644 index 0000000000..6317e56325 --- /dev/null +++ b/src/vendorcode/amd/agesa/f14/Proc/Mem/Ardk/DR/maudr3.c @@ -0,0 +1,260 @@ +/* $NoKeywords:$ */ +/* + * @file + * + * maudr3.c + * + * Platform specific settings for DR DDR3 unbuffered dimms + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/Ardk) + * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 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. + * + * *************************************************************************** + * + */ + +/* This file contains routine that add platform specific support AM3 */ + + +#include "AGESA.h" +#include "mport.h" +#include "PlatformMemoryConfiguration.h" +#include "ma.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "Filecode.h" +CODE_GROUP (G2_PEI) +RDATA_GROUP (G2_PEI) + +#define FILECODE PROC_MEM_ARDK_DR_MAUDR3_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + +STATIC CONST UINT8 ROMDATA DrUDdr3CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +// Even chip select maps to M[B,A]_CKE[0] +// Odd chip select maps to M[B,A]_CKE[1] +STATIC CONST UINT8 ROMDATA DrUDdr3CKETri[] = {0x55, 0xAA}; +// Bit 0: M[B,A]0_ODT[0] +// Bit 1: M[B,A]1_ODT[0] +// Bit 2: M[B,A]0_ODT[1] +// Bit 3: M[B,A]1_ODT[1] +STATIC CONST UINT8 ROMDATA DrUDdr3ODTTri[] = {0x01, 0x04, 0x02, 0x08}; +// Bit 0: M[B,A]0_CS_H/L[0] +// Bit 1: M[B,A]0_CS_H/L[1] +// Bit 2: M[B,A]0_CS_H/L[2] +// Bit 3: M[B,A]0_CS_H/L[3] +STATIC CONST UINT8 ROMDATA DrUDdr3CSTri[] = {0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00}; + +/* -----------------------------------------------------------------------------*/ +/** + * + * This is function sets the platform specific settings for DR DDR3 Unbuffered dimms + * + * + * @param[in,out] *MemData Pointer to MEM_DATA_STRUCTURE + * @param[in] SocketID Socket number + * @param[in,out] *CurrentChannel Pointer to CH_DEF_STRUCT + * + * @return AGESA_SUCCESS + * @return CurrentChannel->MemClkDisMap Points this pointer to RB MemClkDis table + * @return CurrentChannel->ChipSelTriMap Points this pointer to RB CS table + * @return CurrentChannel->CKETriMap Points this pointer to RB ODT table + * @return CurrentChannel->ODTTriMap Points this pointer to RB CKE table + * @return CurrentChannel->DctEccDQSLike Indicates the bytes that should be averaged for ECC + * @return CurrentChannel->DctEccDQSScale Indicates the scale that should be used for Averaging ECC byte + * @return CurrentChannel->DctAddrTmg Address Command Timing Settings for specified channel + * @return CurrentChannel->DctOdcCtl Drive Strength settings for specified channel + * @return CurrentChannel->SlowMode Slow Mode + * + */ + +AGESA_STATUS +MemAGetPsCfgUDr3 ( + IN OUT MEM_DATA_STRUCT *MemData, + IN UINT8 SocketID, + IN OUT CH_DEF_STRUCT *CurrentChannel + ) +{ + STATIC CONST PSCFG_ENTRY PSCfg1Dimm[] = { + {DDR800_FREQUENCY, 0x10, 0x003B0000, 0x20113222}, + {DDR1066_FREQUENCY, 0x10, 0x00380000, 0x20113222}, + {DDR1333_FREQUENCY, 0x10, 0x00360000, 0x20113222}, + {DDR1600_FREQUENCY, 0x10, 0x00340000, 0x20113222} + }; + STATIC CONST PSCFG_ENTRY PSCfg2Dimm[] = { + {DDR800_FREQUENCY, 0xFF, 0x00390039, 0x20223323}, + {DDR1066_FREQUENCY, 0xFF, 0x00350037, 0x20223323}, + {DDR1333_FREQUENCY, 0xFF, 0x00000035, 0x20223323}, + {DDR1600_FREQUENCY, 0xFF, 0x00000033, 0x20223323} + }; + + STATIC CONST ADV_R_PSCFG_WL_ODT_ENTRY PSCfgDIMMWlODT[] = { + {SR_DIMM0, {0x01, 0x00, 0x00, 0x00}, 1}, + {DR_DIMM0, {0x04, 0x00, 0x00, 0x00}, 1}, + {SR_DIMM1, {0x00, 0x02, 0x00, 0x00}, 1}, + {DR_DIMM1, {0x00, 0x08, 0x00, 0x00}, 1}, + {SR_DIMM0 + DR_DIMM0 + SR_DIMM1 + DR_DIMM1, {0x03, 0x03, 0x00, 0x00}, 2} + }; + + UINT16 i; + UINT16 j; + UINT8 Loads; + UINT8 Dimms; + UINT16 Speed; + UINT16 DIMMRankType; + UINT16 _DIMMRankType; + UINT32 AddrTmgCTL; + UINT32 DctOdcCtl; + UINT8 PhyWLODT[4]; + BOOLEAN SlowMode; + UINT8 DimmTpMatch; + + ASSERT (MemData != 0); + ASSERT (CurrentChannel != 0); + AddrTmgCTL = 0; + DctOdcCtl = 0; + PhyWLODT[0] = 0x0F; + PhyWLODT[1] = 0x0F; + PhyWLODT[2] = 0x0F; + PhyWLODT[3] = 0x0F; + + if ((CurrentChannel->MCTPtr->LogicalCpuid.Family & AMD_FAMILY_10_RB) == 0) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->TechType != DDR3_TECHNOLOGY) { + return AGESA_UNSUPPORTED; + } + if (CurrentChannel->RegDimmPresent != 0) { + return AGESA_UNSUPPORTED; + } + // Prepare inputs + Loads = CurrentChannel->Loads; + Dimms = CurrentChannel->Dimms; + Speed = CurrentChannel->DCTPtr->Timings.Speed; + + DIMMRankType = MemAGetPsRankType (CurrentChannel); + + if ((Speed == DDR1333_FREQUENCY || Speed == DDR1600_FREQUENCY) && (Dimms == 2)) { + SlowMode = TRUE; // 2T + } else if ((Speed == DDR1600_FREQUENCY) && (Dimms == 1) && (Loads >= 16)) { + SlowMode = TRUE; // 2T + } else { + SlowMode = FALSE; // 1T + } + + if (Dimms == 1) { + for (i = 0; i < GET_SIZE_OF (PSCfg1Dimm); i++) { + if (Speed == PSCfg1Dimm[i].Speed) { + if (Loads >= PSCfg1Dimm[i].Loads) { + AddrTmgCTL = PSCfg1Dimm[i].AddrTmg; + DctOdcCtl = PSCfg1Dimm[i].Odc; + } else { + DctOdcCtl = 0x20113222; + } + break; + } + } + ASSERT (i < GET_SIZE_OF (PSCfg1Dimm)); + } else { + for (i = 0; i < GET_SIZE_OF (PSCfg2Dimm); i++) { + if (Speed == PSCfg2Dimm[i].Speed) { + if (Loads <= PSCfg2Dimm[i].Loads) { + AddrTmgCTL = PSCfg2Dimm[i].AddrTmg; + DctOdcCtl = PSCfg2Dimm[i].Odc; + break; + } + } + } + ASSERT (i < GET_SIZE_OF (PSCfg2Dimm)); + } + + // WL ODT + for (i = 0; i < GET_SIZE_OF (PSCfgDIMMWlODT); i++) { + if (Dimms != PSCfgDIMMWlODT[i].Dimms) { + continue; + } + DimmTpMatch = 0; + _DIMMRankType = DIMMRankType & PSCfgDIMMWlODT[i].DIMMRankType; + for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) { + if ((_DIMMRankType & (UINT16) 0x0F << (j << 2)) != 0) { + DimmTpMatch++; + } + } + if (DimmTpMatch == PSCfgDIMMWlODT[i].Dimms) { + PhyWLODT[0] = PSCfgDIMMWlODT[i].PhyWrLvOdt[0]; + PhyWLODT[1] = PSCfgDIMMWlODT[i].PhyWrLvOdt[1]; + PhyWLODT[2] = PSCfgDIMMWlODT[i].PhyWrLvOdt[2]; + PhyWLODT[3] = PSCfgDIMMWlODT[i].PhyWrLvOdt[3]; + break; + } + } + + CurrentChannel->MemClkDisMap = (UINT8 *) DrUDdr3CLKDis; + CurrentChannel->CKETriMap = (UINT8 *) DrUDdr3CKETri; + CurrentChannel->ODTTriMap = (UINT8 *) DrUDdr3ODTTri; + CurrentChannel->ChipSelTriMap = (UINT8 *) DrUDdr3CSTri; + + CurrentChannel->DctEccDqsLike = 0x0403; + CurrentChannel->DctEccDqsScale = 0x70; + CurrentChannel->DctAddrTmg = AddrTmgCTL; + CurrentChannel->DctOdcCtl = DctOdcCtl; + for (i = 0; i < sizeof (CurrentChannel->PhyWLODT); i++) { + CurrentChannel->PhyWLODT[i] = PhyWLODT[i]; + } + CurrentChannel->SlowMode = SlowMode; + + return AGESA_SUCCESS; +} |