aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c
new file mode 100644
index 0000000000..b153eef71e
--- /dev/null
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c
@@ -0,0 +1,328 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ */
+
+/* This file contains functions for common utility functions */
+
+/*
+ *-----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
+{
+ /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
+
+ AmdMemPCIRead(loc, pValue);
+ *pValue = *pValue >> lowbit; /* Shift */
+
+ /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
+ if ((highbit-lowbit) != 31)
+ *pValue &= (((u32)1 << (highbit-lowbit+1))-1);
+}
+
+static void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
+{
+ u32 temp, mask;
+
+ /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
+
+ /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
+ if ((highbit-lowbit) != 31)
+ mask = (((u32)1 << (highbit-lowbit+1))-1);
+ else
+ mask = (u32)0xFFFFFFFF;
+
+ AmdMemPCIRead(loc, &temp);
+ temp &= ~(mask << lowbit);
+ temp |= (*pValue & mask) << lowbit;
+ AmdMemPCIWrite(loc, &temp);
+}
+
+/*-----------------------------------------------------------------------------
+ * uint 32
+ * u32 bitTestSet(u32 csMask,u32 tempD)
+ *
+ * Description:
+ * This routine sets a bit in a u32
+ *
+ * Parameters:
+ * IN csMask = Target value in which the bit will be set
+ * IN tempD = Bit that will be set
+ * OUT value = Target value with the bit set
+ *-----------------------------------------------------------------------------
+ */
+static u32 bitTestSet(u32 csMask,u32 tempD)
+{
+ u32 localTemp;
+ /* ASSERT(tempD < 32); */
+ localTemp = 1;
+ csMask |= localTemp << tempD;
+ return csMask;
+}
+
+/*-----------------------------------------------------------------------------
+ * uint 32
+ * u32 bitTestReset(u32 csMask,u32 tempD)
+ *
+ * Description:
+ * This routine re-sets a bit in a u32
+ *
+ * Parameters:
+ * IN csMask = Target value in which the bit will be re-set
+ * IN tempD = Bit that will be re-set
+ * OUT value = Target value with the bit re-set
+ *-----------------------------------------------------------------------------
+ */
+static u32 bitTestReset(u32 csMask,u32 tempD)
+{
+ u32 temp, localTemp;
+ /* ASSERT(tempD < 32); */
+ localTemp = 1;
+ temp = localTemp << tempD;
+ temp = ~temp;
+ csMask &= temp;
+ return csMask;
+}
+
+/*-----------------------------------------------------------------------------
+ * uint 32
+ * u32 get_Bits(DCTStruct *DCTData, u8 DCT, u8 Node, u8 func, u16 offset,
+ * u8 low, u8 high)
+ *
+ * Description:
+ * This routine Gets the PCT bits from the specidfied Node, DCT and PCI address
+ *
+ * Parameters:
+ * IN OUT *DCTData - Pointer to buffer with information about each DCT
+ * IN DCT - DCT number
+ * - 1 indicates DCT 1
+ * - 0 indicates DCT 0
+ * - 2 both DCTs
+ * Node - Node number
+ * Func - PCI Function number
+ * Offset - PCI register number
+ * Low - Low bit of the bit field
+ * High - High bit of the bit field
+ *
+ * OUT value = Value read from PCI space
+ *-----------------------------------------------------------------------------
+ */
+static u32 get_Bits(sDCTStruct *pDCTData,
+ u8 dct, u8 node, u8 func,
+ u16 offset, u8 low, u8 high)
+{
+ u32 temp;
+ /* ASSERT(node < MAX_NODES); */
+ if (dct == BOTH_DCTS)
+ {
+ /* Registers exist on DCT0 only */
+ AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ else
+ {
+ if (dct == 1)
+ {
+ /* Write to dct 1 */
+ offset += 0x100;
+ AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ else
+ {
+ /* Write to dct 0 */
+ AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ }
+ return temp;
+}
+
+/*-----------------------------------------------------------------------------
+ * uint 32
+ * void set_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func, u16 offset,
+ * u8 low, u8 high, u32 value)
+ *
+ * Description:
+ * This routine Sets the PCT bits from the specidfied Node, DCT and PCI address
+ *
+ * Parameters:
+ * IN OUT *DCTData - Pointer to buffer with information about each DCT
+ * IN DCT - DCT number
+ * - 1 indicates DCT 1
+ * - 0 indicates DCT 0
+ * - 2 both DCTs
+ * Node - Node number
+ * Func - PCI Function number
+ * Offset - PCI register number
+ * Low - Low bit of the bit field
+ * High - High bit of the bit field
+ *
+ * OUT
+ *-----------------------------------------------------------------------------
+ */
+static void set_Bits(sDCTStruct *pDCTData,
+ u8 dct, u8 node, u8 func,
+ u16 offset, u8 low, u8 high, u32 value)
+{
+ u32 temp;
+ temp = value;
+
+ if (dct == BOTH_DCTS)
+ {
+ /* Registers exist on DCT0 only */
+ AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ else
+ {
+ if (dct == 1)
+ {
+ /* Write to dct 1 */
+ offset += 0x100;
+ AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ else
+ {
+ /* Write to dct 0 */
+ AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
+ }
+ }
+}
+
+/*-------------------------------------------------
+ * uint 32
+ * u32 get_ADD_DCT_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func,
+ * u16 offset,u8 low, u8 high)
+ *
+ * Description:
+ * This routine gets the Additional PCT register from Function 2 by specidfied
+ * Node, DCT and PCI address
+ *
+ * Parameters:
+ * IN OUT *DCTData - Pointer to buffer with information about each DCT
+ * IN DCT - DCT number
+ * - 1 indicates DCT 1
+ * - 0 indicates DCT 0
+ * - 2 both DCTs
+ * Node - Node number
+ * Func - PCI Function number
+ * Offset - Additional PCI register number
+ * Low - Low bit of the bit field
+ * High - High bit of the bit field
+ *
+ * OUT
+ *-------------------------------------------------
+ */
+static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
+ u8 dct, u8 node, u8 func,
+ u16 offset, u8 low, u8 high)
+{
+ u32 tempD;
+ tempD = offset;
+ tempD = bitTestReset(tempD,DctAccessWrite);
+ set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
+ PCI_MIN_LOW, PCI_MAX_HIGH, offset);
+ while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
+ DctAccessDone, DctAccessDone)) == 0);
+ return (get_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
+ low, high));
+}
+
+/*-------------------------------------------------
+ * uint 32
+ * void set_DCT_ADDR_Bits(DCTStruct *DCTData, u8 DCT,u8 Node,u8 func,
+ * u16 offset,u8 low, u8 high, u32 value)
+ *
+ * Description:
+ * This routine sets the Additional PCT register from Function 2 by specidfied
+ * Node, DCT and PCI address
+ *
+ * Parameters:
+ * IN OUT *DCTData - Pointer to buffer with information about each DCT
+ * IN DCT - DCT number
+ * - 1 indicates DCT 1
+ * - 0 indicates DCT 0
+ * - 2 both DCTs
+ * Node - Node number
+ * Func - PCI Function number
+ * Offset - Additional PCI register number
+ * Low - Low bit of the bit field
+ * High - High bit of the bit field
+ *
+ * OUT
+ *-------------------------------------------------
+ */
+static void set_DCT_ADDR_Bits(sDCTStruct *pDCTData,
+ u8 dct, u8 node, u8 func,
+ u16 offset, u8 low, u8 high, u32 value)
+{
+ u32 tempD;
+
+ set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
+ PCI_MIN_LOW, PCI_MAX_HIGH, offset);
+ while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
+ DctAccessDone, DctAccessDone)) == 0);
+
+ set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
+ low, high, value);
+ tempD = offset;
+ tempD = bitTestSet(tempD,DctAccessWrite);
+ set_Bits(pDCTData, dct, node, FUN_DCT,DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
+ PCI_MIN_LOW, PCI_MAX_HIGH, tempD);
+ while ((get_Bits(pDCTData,dct, pDCTData->NodeId, FUN_DCT,
+ DRAM_CONTROLLER_ADD_DATA_OFFSET_REG, DctAccessDone,
+ DctAccessDone)) == 0);
+}
+
+/*-------------------------------------------------
+ * uint 32
+ * BOOL bitTest(u32 value, u8 bitLoc)
+ *
+ * Description:
+ * This routine tests the value to determine if the bitLoc is set
+ *
+ * Parameters:
+ * IN Value - value to be tested
+ * bitLoc - bit location to be tested
+ * OUT TRUE - bit is set
+ * FALSE - bit is clear
+ *-------------------------------------------------
+ */
+static BOOL bitTest(u32 value, u8 bitLoc)
+{
+ u32 tempD, compD;
+ tempD = value;
+ compD = 0;
+ compD = bitTestSet(compD,bitLoc);
+ tempD &= compD;
+ if (compD == tempD)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}