| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * Initialize PP/DPM fuse table. |
| * |
| * |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: GNB |
| * @e \$Revision: 64211 $ @e \$Date: 2012-01-17 23:00:25 -0600 (Tue, 17 Jan 2012) $ |
| * |
| */ |
| /* |
| ***************************************************************************** |
| * |
| * Copyright (c) 2008 - 2012, 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. |
| * *************************************************************************** |
| * |
| */ |
| |
| /*---------------------------------------------------------------------------------------- |
| * M O D U L E S U S E D |
| *---------------------------------------------------------------------------------------- |
| */ |
| #include "AGESA.h" |
| #include "amdlib.h" |
| #include "Ids.h" |
| #include "Gnb.h" |
| #include "GnbPcie.h" |
| #include "GnbCommonLib.h" |
| #include "GnbNbInitLibV4.h" |
| #include "GnbRegisterAccTN.h" |
| #include "GnbRegistersTN.h" |
| #include "Filecode.h" |
| #define FILECODE PROC_GNB_MODULES_GNBINITTN_GNBREGISTERACCTN_FILECODE |
| /*---------------------------------------------------------------------------------------- |
| * D E F I N I T I O N S A N D M A C R O S |
| *---------------------------------------------------------------------------------------- |
| */ |
| #define GNB_IGNORED_PARAM 0xFF |
| #define ORB_WRITE_ENABLE 0x100 |
| #define IOMMU_L1_WRITE_ENABLE 0x80000000ul |
| #define IOMMU_L2_WRITE_ENABLE 0x100 |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * T Y P E D E F S A N D S T R U C T U R E S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * P R O T O T Y P E S O F L O C A L F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| VOID |
| GnbRegisterWriteTNDump ( |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| IN VOID *Value |
| ); |
| AGESA_STATUS |
| GnbRegisterReadServiceTN ( |
| IN GNB_HANDLE *GnbHandle, |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| OUT VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| |
| AGESA_STATUS |
| GnbRegisterWriteServiceTN ( |
| IN GNB_HANDLE *GnbHandle, |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| IN VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Config Dct and Mp. |
| * |
| * |
| * |
| * @param[in] DctCfgSel Dct0/Dct1 |
| * @param[in] MemPsSel Mp0/Mp1 |
| * @param[in] StdHeader Standard configuration header |
| * |
| * @return true - Memory Pstate context has been changed |
| * @return false - Memory Pstate context has not been changed |
| */ |
| STATIC BOOLEAN |
| GnbDctMpConfigTN ( |
| IN UINT8 DctCfgSel, |
| IN UINT8 MemPsSel, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| // Select DCT and memory P-state, D18F1x10C[DctCfgSel], D18F1x10C[MemPsSel] |
| D18F1x10C_STRUCT D18F1x10C; |
| BOOLEAN MemPsChangd; |
| ACCESS_WIDTH Width; |
| |
| MemPsChangd = FALSE; |
| Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 1, D18F1x10C_ADDRESS), |
| Width, |
| &D18F1x10C.Value, |
| StdHeader |
| ); |
| |
| if ((DctCfgSel != 0xFF) && (DctCfgSel < 2)) { |
| D18F1x10C.Field.DctCfgSel = DctCfgSel; |
| } |
| |
| if ((MemPsSel != 0xFF) && (MemPsSel < 2) && (D18F1x10C.Field.MemPsSel != MemPsSel)) { |
| //Switches Mem Pstate |
| D18F1x10C.Field.MemPsSel = MemPsSel; |
| MemPsChangd = TRUE; |
| } |
| |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 1, D18F1x10C_ADDRESS), |
| Width, |
| &D18F1x10C.Value, |
| StdHeader |
| ); |
| |
| return MemPsChangd; |
| |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to Read Dct Additional Data. |
| * |
| * |
| * |
| * @param[in] Address D18F2x9c Register offset |
| * @param[in] DctCfgSel Dct0/Dct1 |
| * @param[in] MemPsSel Mp0/Mp1 |
| * @param[out] Value Read value |
| * @param[in] StdHeader Standard configuration header |
| */ |
| STATIC VOID |
| GnbDctAdditionalDataReadTN ( |
| IN UINT32 Address, |
| IN UINT8 DctCfgSel, |
| IN UINT8 MemPsSel, |
| IN UINT32 Flags, |
| OUT VOID *Value, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| D18F2x98_dct0_STRUCT D18F2x98; |
| BOOLEAN PstateChanged; |
| ACCESS_WIDTH Width; |
| |
| Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; |
| |
| PstateChanged = GnbDctMpConfigTN ( |
| DctCfgSel, |
| MemPsSel, |
| Flags, |
| StdHeader |
| ); |
| |
| // Clear DctAccessWrite |
| D18F2x98.Field.DctOffset = Address & 0x3FFFFFFF; |
| D18F2x98.Field.DctAccessWrite = 0; |
| |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, ((DctCfgSel == 0) ? D18F2x98_dct0_ADDRESS : D18F2x98_dct1_ADDRESS)), |
| Width, |
| &D18F2x98.Value, |
| StdHeader |
| ); |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, ((DctCfgSel == 0) ? D18F2x9C_dct0_ADDRESS : D18F2x9C_dct1_ADDRESS)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| DctCfgSel, |
| ((MemPsSel == 0) ? 1 : 0), |
| Flags, |
| StdHeader |
| ); |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to Write Dct Additional Data. |
| * |
| * |
| * |
| * @param[in] Address D18F2x9c Register offset |
| * @param[in] DctCfgSel Dct0/Dct1 |
| * @param[in] MemPsSel Mp0/Mp1 |
| * @param[in] Value Write value |
| * @param[in] StdHeader Standard configuration header |
| */ |
| STATIC VOID |
| GnbDctAdditionalDataWriteTN ( |
| IN UINT32 Address, |
| IN UINT8 DctCfgSel, |
| IN UINT8 MemPsSel, |
| IN UINT32 Flags, |
| IN VOID *Value, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| D18F2x98_dct0_STRUCT D18F2x98; |
| BOOLEAN PstateChanged; |
| ACCESS_WIDTH Width; |
| |
| Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; |
| |
| PstateChanged = GnbDctMpConfigTN ( |
| DctCfgSel, |
| MemPsSel, |
| Flags, |
| StdHeader |
| ); |
| |
| // Put write data on |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, ((DctCfgSel == 0) ? D18F2x9C_dct0_ADDRESS : D18F2x9C_dct1_ADDRESS)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| |
| // Set DctAccessWrite |
| D18F2x98.Field.DctOffset = Address & 0x3FFFFFFF; |
| D18F2x98.Field.DctAccessWrite = 1; |
| |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, ((DctCfgSel == 0) ? D18F2x98_dct0_ADDRESS : D18F2x98_dct1_ADDRESS)), |
| Width, |
| &D18F2x98.Value, |
| StdHeader |
| ); |
| |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| DctCfgSel, |
| ((MemPsSel == 0) ? 1 : 0), |
| Flags, |
| StdHeader |
| ); |
| } |
| } |
| |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to read all register spaces. |
| * |
| * |
| * |
| * @param[in] GnbHandle GNB handle |
| * @param[in] RegisterSpaceType Register space type |
| * @param[in] Address Register offset, but PortDevice |
| * @param[out] Value Return value |
| * @param[in] Flags Flags - BIT0 indicates S3 save/restore |
| * @param[in] StdHeader Standard configuration header |
| */ |
| AGESA_STATUS |
| GnbRegisterReadServiceTN ( |
| IN GNB_HANDLE *GnbHandle, |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| OUT VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| return GnbRegisterReadTN (RegisterSpaceType, Address, Value, Flags, StdHeader); |
| } |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to read all register spaces. |
| * |
| * |
| * |
| * @param[in] RegisterSpaceType Register space type |
| * @param[in] Address Register offset, but PortDevice |
| * @param[out] Value Return value |
| * @param[in] Flags Flags - BIT0 indicates S3 save/restore |
| * @param[in] StdHeader Standard configuration header |
| */ |
| AGESA_STATUS |
| GnbRegisterReadTN ( |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| OUT VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| ACCESS_WIDTH Width; |
| UINT32 TempValue; |
| UINT32 TempAddress; |
| BOOLEAN PstateChanged; |
| |
| Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; |
| TempAddress = 0; |
| TempValue = 0; |
| |
| |
| switch (RegisterSpaceType) { |
| case TYPE_D0F0: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0, 0, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D0F2: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D1F0: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 1, 0, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D1F1: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 1, 1, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_DxF0: |
| // Treat it as complete address for ports |
| GnbLibPciRead ( |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F1: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 1, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F2: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F3: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 3, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F4: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 4, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F5: |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 5, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0x64: |
| // Miscellaneous Index Data, access the registers D0F0x64_x[FF:00] |
| // Write enable bit7 |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0x98: |
| // Northbridge ORB Configuration Offset, access D0F0x98_x[FF:00] |
| // Write enable bit8 |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0x94_ADDRESS), |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0xBC: |
| { |
| //SMU, access D0F0xBC_x[FFFFFFFF:00000000] |
| // No write enable |
| UINT64 TempData; |
| //ASSERT ((Address < 0xE0100000 || Address > 0xE0108FFFF) && (Address & 0x3) == 0); |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0xB8_ADDRESS), |
| (Address & (~0x3ull)), |
| Width, |
| &TempData, |
| StdHeader |
| ); |
| if ((Address & 0x3) != 0) { |
| //Non aligned access allowed to fuse block |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0xB8_ADDRESS), |
| (Address & (~0x3ull)) + 4, |
| Width, |
| ((UINT32 *) &TempData) + 1, |
| StdHeader |
| ); |
| } |
| * ((UINT32*) Value) = (UINT32) (TempData >> ((Address & 0x3) * 8)); |
| break; |
| } |
| case TYPE_D0F0xE4: |
| // D0F0xE0 Link Index Address, access D0F0xE4_x[FFFF_FFFF:0000_0000] |
| // No write enable |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0xE0_ADDRESS), |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F2xF4: |
| // IOMMU L2 Config Index, to access the registers D0F2xF4_x[FF:00]. |
| // Write enable bit8 |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 2, 0xF0),//D0F2xF0_ADDRESS |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F2xFC: |
| // IOMMU L1 Config Index, access the registers D0F2xFC_x[FFFF:0000]_L1[3:0] |
| // Write enable bit31 |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 2, 0xF8),//D0F2xF8_ADDRESS |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_DxF0xE4: |
| // D[8:2]F0xE0 Root Port Index, access the registers D[8:2]F0xE4_x[FF:00] |
| // No write enable |
| TempValue = ((Address >> 16) & 0xFF); |
| TempAddress = Address & 0xFF; |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, (TempValue), 0, 0xE0),//DxF0xE0_ADDRESS |
| TempAddress, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_MSR: |
| LibAmdMsrRead (Address, Value, StdHeader); |
| break; |
| |
| case TYPE_GMM: |
| ASSERT (Address < 0x40000); |
| |
| if ((Address >= 0x600) && (Address <= 0x8FF)) { |
| // CG |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (Address - 0x600)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| } else { |
| // SRBM |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0x80080000 | (Address & 0x3FFFF)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2x9C_dct0: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 0, |
| GNB_IGNORED_PARAM, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct0_mp0: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 0, |
| 0, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct0_mp1: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 0, |
| 1, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 1, |
| GNB_IGNORED_PARAM, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1_mp0: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 1, |
| 0, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1_mp1: |
| GnbDctAdditionalDataReadTN ( |
| Address, |
| 1, |
| 1, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct0: |
| GnbDctMpConfigTN ( |
| 0, |
| GNB_IGNORED_PARAM, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct0_mp0: |
| PstateChanged = GnbDctMpConfigTN ( |
| 0, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 0, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct0_mp1: |
| PstateChanged = GnbDctMpConfigTN ( |
| 0, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 0, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct1: |
| GnbDctMpConfigTN ( |
| 1, |
| GNB_IGNORED_PARAM, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct1_mp0: |
| PstateChanged = GnbDctMpConfigTN ( |
| 1, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 1, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct1_mp1: |
| PstateChanged = GnbDctMpConfigTN ( |
| 1, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciRead ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 1, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_CGIND: |
| // CG index |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (0x8F8 - 0x600)), |
| Width, |
| &Address, |
| StdHeader |
| ); |
| // CG data |
| GnbLibPciIndirectRead ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (0x8FC - 0x600)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| default: |
| ASSERT (FALSE); |
| break; |
| } |
| |
| |
| |
| |
| return AGESA_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to write all register spaces. |
| * |
| * |
| * |
| * @param[in] GnbHandle GnbHandle |
| * @param[in] RegisterSpaceType Register space type |
| * @param[in] Address Register offset, but PortDevice |
| * @param[out] Value The value to write |
| * @param[in] Flags Flags - BIT0 indicates S3 save/restore |
| * @param[in] StdHeader Standard configuration header |
| */ |
| AGESA_STATUS |
| GnbRegisterWriteServiceTN ( |
| IN GNB_HANDLE *GnbHandle, |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| IN VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| return GnbRegisterWriteTN (RegisterSpaceType, Address, Value, Flags, StdHeader); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to write all register spaces. |
| * |
| * |
| * |
| * @param[in] RegisterSpaceType Register space type |
| * @param[in] Address Register offset, but PortDevice |
| * @param[out] Value The value to write |
| * @param[in] Flags Flags - BIT0 indicates S3 save/restore |
| * @param[in] StdHeader Standard configuration header |
| */ |
| AGESA_STATUS |
| GnbRegisterWriteTN ( |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| IN VOID *Value, |
| IN UINT32 Flags, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| |
| ACCESS_WIDTH Width; |
| UINT32 TempValue; |
| UINT32 TempAddress; |
| PCI_ADDR PciAddress; |
| BOOLEAN PstateChanged; |
| |
| Width = (Flags == GNB_REG_ACC_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; |
| TempAddress = 0; |
| TempValue = 0; |
| |
| GNB_DEBUG_CODE ( |
| GnbRegisterWriteTNDump (RegisterSpaceType, Address, Value); |
| ); |
| |
| switch (RegisterSpaceType) { |
| case TYPE_D0F0: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D0F2: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D1F0: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 1, 0, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D1F1: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 1, 1, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_DxF0: |
| // Treat it as complete address for ports |
| GnbLibPciWrite ( |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F1: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 1, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F2: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F3: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 3, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F4: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 4, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_D18F5: |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 5, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0x64: |
| // Miscellaneous Index Data, access the registers D0F0x64_x[FF:00] |
| // Write enable bit7 |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), |
| Address | IOC_WRITE_ENABLE, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0x98: |
| // Northbridge ORB Configuration Offset, access D0F0x98_x[FF:00] |
| // Write enable bit8 |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0x94_ADDRESS), |
| Address | ORB_WRITE_ENABLE, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0xBC: |
| //SMU, access D0F0xBC_x[FFFFFFFF:00000000] |
| // No write enable |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F0xE4: |
| // D0F0xE0 Link Index Address, access D0F0xE4_x[FFFF_FFFF:0000_0000] |
| // No write enable |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, D0F0xE0_ADDRESS), |
| Address, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F2xF4: |
| // IOMMU L2 Config Index, to access the registers D0F2xF4_x[FF:00]. |
| // Write enable bit8 |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 2, 0xF0),//D0F2xF0_ADDRESS |
| Address | IOMMU_L2_WRITE_ENABLE, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D0F2xFC: |
| // IOMMU L1 Config Index, access the registers D0F2xFC_x[FFFF:0000]_L1[3:0] |
| // Write enable bit31 |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 2, 0xF8),//D0F2xF8_ADDRESS |
| Address | IOMMU_L1_WRITE_ENABLE, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_DxF0xE4: |
| // D[8:2]F0xE0 Root Port Index, access the registers D[8:2]F0xE4_x[FF:00] |
| // No write enable |
| TempValue = ((Address >> 16) & 0xFF); |
| TempAddress = Address & 0xFF; |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, (TempValue), 0, 0xE0),//DxF0xE0_ADDRESS |
| TempAddress, |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_MSR: |
| LibAmdMsrWrite (Address, Value, StdHeader); |
| break; |
| |
| case TYPE_GMM: |
| ASSERT (Address < 0x40000); |
| |
| if ((Address >= 0x600) && (Address <= 0x8FF)) { |
| // CG |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (Address - 0x600)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| } else { |
| // SRBM |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0x80080000 | (Address & 0x3FFFF)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2x9C_dct0: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 0, |
| GNB_IGNORED_PARAM, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct0_mp0: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 0, |
| 0, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct0_mp1: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 0, |
| 1, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 1, |
| GNB_IGNORED_PARAM, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1_mp0: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 1, |
| 0, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2x9C_dct1_mp1: |
| GnbDctAdditionalDataWriteTN ( |
| Address, |
| 1, |
| 1, |
| Flags, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct0: |
| GnbDctMpConfigTN ( |
| 0, |
| GNB_IGNORED_PARAM, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct0_mp0: |
| PstateChanged = GnbDctMpConfigTN ( |
| 0, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 0, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct0_mp1: |
| PstateChanged = GnbDctMpConfigTN ( |
| 0, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 0, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct1: |
| GnbDctMpConfigTN ( |
| 1, |
| GNB_IGNORED_PARAM, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| |
| case TYPE_D18F2_dct1_mp0: |
| PstateChanged = GnbDctMpConfigTN ( |
| 1, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 1, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_D18F2_dct1_mp1: |
| PstateChanged = GnbDctMpConfigTN ( |
| 1, |
| 1, |
| Flags, |
| StdHeader |
| ); |
| GnbLibPciWrite ( |
| MAKE_SBDFO (0, 0, 0x18, 2, Address), |
| Width, |
| Value, |
| StdHeader |
| ); |
| if (PstateChanged) { |
| GnbDctMpConfigTN ( |
| 1, |
| 0, |
| Flags, |
| StdHeader |
| ); |
| } |
| break; |
| |
| case TYPE_CGIND: |
| // CG index |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (0x8F8 - 0x600)), |
| Width, |
| &Address, |
| StdHeader |
| ); |
| // CG data |
| GnbLibPciIndirectWrite ( |
| MAKE_SBDFO (0, 0, 0, 0, 0xB8), |
| (0xE0002000 | (0x8FC - 0x600)), |
| Width, |
| Value, |
| StdHeader |
| ); |
| break; |
| case TYPE_SMU_MSG: |
| PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); |
| GnbSmuServiceRequestV4 (PciAddress, (UINT8) Address, Flags, StdHeader); |
| break; |
| default: |
| ASSERT (FALSE); |
| break; |
| } |
| |
| return AGESA_SUCCESS; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /* |
| * Routine to dump all write register spaces. |
| * |
| * |
| * |
| * @param[in] RegisterSpaceType Register space type |
| * @param[in] Address Register offset |
| * @param[in] Value The value to write |
| */ |
| VOID |
| GnbRegisterWriteTNDump ( |
| IN UINT8 RegisterSpaceType, |
| IN UINT32 Address, |
| IN VOID *Value |
| ) |
| { |
| IDS_HDT_CONSOLE (NB_MISC, " R WRITE Space %s Address 0x%04x, Value 0x%04x\n", |
| (RegisterSpaceType == TYPE_D0F0) ? "TYPE_D0F0" : ( |
| (RegisterSpaceType == TYPE_D0F0x64) ? "TYPE_D0F0x64" : ( |
| (RegisterSpaceType == TYPE_D0F0x98) ? "TYPE_D0F0x98" : ( |
| (RegisterSpaceType == TYPE_D0F0xBC) ? "TYPE_D0F0xBC" : ( |
| (RegisterSpaceType == TYPE_D0F0xE4) ? "TYPE_D0F0xE4" : ( |
| (RegisterSpaceType == TYPE_DxF0) ? "TYPE_DxF0" : ( |
| (RegisterSpaceType == TYPE_DxF0xE4) ? "TYPE_DxF0xE4" : ( |
| (RegisterSpaceType == TYPE_D0F2) ? "TYPE_D0F2" : ( |
| (RegisterSpaceType == TYPE_D0F2xF4) ? "TYPE_D0F2xF4" : ( |
| (RegisterSpaceType == TYPE_D0F2xFC) ? "TYPE_D0F2xFC" : ( |
| (RegisterSpaceType == TYPE_D18F1) ? "TYPE_D18F1" : ( |
| (RegisterSpaceType == TYPE_D18F2) ? "TYPE_D18F2" : ( |
| (RegisterSpaceType == TYPE_D18F3) ? "TYPE_D18F3" : ( |
| (RegisterSpaceType == TYPE_D18F4) ? "TYPE_D18F4" : ( |
| (RegisterSpaceType == TYPE_D18F5) ? "TYPE_D18F5" : ( |
| (RegisterSpaceType == TYPE_MSR) ? "TYPE_MSR" : ( |
| (RegisterSpaceType == TYPE_D1F0) ? "TYPE_D1F0" : ( |
| (RegisterSpaceType == TYPE_D1F1) ? "TYPE_D1F1" : ( |
| (RegisterSpaceType == TYPE_GMM) ? "TYPE_GMM" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct0) ? "TYPE_D18F2x9C_dct0" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct0_mp0) ? "TYPE_D18F2x9C_dct0_mp0" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct0_mp1) ? "TYPE_D18F2x9C_dct0_mp1" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct1) ? "TYPE_D18F2x9C_dct1" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct1_mp0) ? "TYPE_D18F2x9C_dct1_mp0" : ( |
| (RegisterSpaceType == TYPE_D18F2x9C_dct1_mp1) ? "TYPE_D18F2x9C_dct1_mp1" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct0) ? "TYPE_D18F2_dct0" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct0_mp0) ? "TYPE_D18F2_dct0_mp0" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct0_mp1) ? "TYPE_D18F2_dct0_mp1" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct1) ? "TYPE_D18F2_dct1" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct1_mp0) ? "TYPE_D18F2_dct1_mp0" : ( |
| (RegisterSpaceType == TYPE_SMU_MSG) ? "TYPE_SMU_MSG" : ( |
| (RegisterSpaceType == TYPE_D18F2_dct1_mp1) ? "TYPE_D18F2_dct1_mp1" : "Invalid"))))))))))))))))))))))))))))))), |
| Address, |
| *((UINT32*)Value) |
| ); |
| } |