Beispiel #1
0
/*-------------------------------------------------
 *  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 specified
 *   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));
}
Beispiel #2
0
/*-------------------------------------------------
 *  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 specified
 *   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);
}
Beispiel #3
0
/*-----------------------------------------------------------------------------
 * u32 swapAddrBits_wl(sDCTStruct *pDCTData, u32 MRSValue)
 *
 * Description:
 *	This function swaps the bits in MSR register value
 *
 * Parameters:
 *	IN  OUT   *DCTData - Pointer to buffer with information about each DCT
 *	IN	u32: MRS value
 *	OUT	u32: Swapped BANK BITS
 *
 * ----------------------------------------------------------------------------
 */
u32 swapAddrBits_wl(sDCTStruct *pDCTData, u32 MRSValue)
{
	u32 tempW, tempW1;

	tempW1 = get_Bits(pDCTData, pDCTData->CurrDct, pDCTData->NodeId,
			FUN_DCT, DRAM_INIT, MrsChipSelStart, MrsChipSelEnd);
	if (tempW1 & 1)
	{
		if ((pDCTData->Status[DCT_STATUS_OnDimmMirror]))
		{
			/* swap A3/A4,A5/A6,A7/A8 */
			tempW = MRSValue;
			tempW1 = MRSValue;
			tempW &= 0x0A8;
			tempW1 &= 0x0150;
			MRSValue &= 0xFE07;
			MRSValue |= (tempW<<1);
			MRSValue |= (tempW1>>1);
		}
	}
Beispiel #4
0
/*-----------------------------------------------------------------------------
 * void AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData,
 *                  u8 Dimm, u8 Pass)
 *
 *  Description:
 *       This function initialized Hardware based write levelization phase 1
 *
 *   Parameters:
 *       IN  OUT   *SPDData - Pointer to buffer with information about each DIMMs
 *                            SPD information
 *                 *MCTData - Pointer to buffer with runtime parameters,
 *                 *DCTData - Pointer to buffer with information about each DCT
 *
 *       IN        DIMM - Logical DIMM number
 *                 Pass - First or Second Pass
 *       OUT
 *-----------------------------------------------------------------------------
 */
void AgesaHwWlPhase1(sMCTStruct *pMCTData, sDCTStruct *pDCTData,
		u8 dimm, u8 pass)
{
	u8 ByteLane;
	u32 Value, Addr;
	u16 Addl_Data_Offset, Addl_Data_Port;

	pDCTData->WLPass = pass;
	/* 1. Specify the target DIMM that is to be trained by programming
	 * F2x[1, 0]9C_x08[TrDimmSel].
	 */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, TrDimmSelStart,
			TrDimmSelEnd,(u32)dimm);
	/* 2. Prepare the DIMMs for write levelization using DDR3-defined
	 * MR commands. */
	prepareDimms(pMCTData, pDCTData,dimm, TRUE);
	/* 3. After the DIMMs are configured, BIOS waits 40 MEMCLKs to
	 *    satisfy DDR3-defined internal DRAM timing.
	 */
	pMCTData->AgesaDelay(40);
	/* 4. Configure the processor's DDR phy for write levelization training: */
	procConifg(pMCTData,pDCTData, dimm, pass);
	/* 5. Begin write levelization training:
	 *  Program F2x[1, 0]9C_x08[WrtLevelTrEn]=1. */
	if (pDCTData->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx))
		set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
				DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 1);
	else
	{
		/* Broadcast write to all D3Dbyte chipset register offset 0xc
		 * Set bit 0 (wrTrain)
		 * Program bit 4 to nibble being trained (only matters for x4dimms)
		 * retain value of 3:2 (Trdimmsel)
		 * reset bit 5 (FrzPR)
		 */
		if (pDCTData->DctTrain)
		{
			Addl_Data_Offset=0x198;
			Addl_Data_Port=0x19C;
		}
		else
		{
			Addl_Data_Offset=0x98;
			Addl_Data_Port=0x9C;
		}
		Addr=0x0D00000C;
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
		while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
				DctAccessDone, DctAccessDone)) == 0);
		AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
		Value = bitTestSet(Value, 0);	/* enable WL training */
		Value = bitTestReset(Value, 4); /* for x8 only */
		Value = bitTestReset(Value, 5); /* for hardware WL training */
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
		Addr=0x4D030F0C;
		AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
		while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
				DctAccessDone, DctAccessDone)) == 0);
	}

	/* Wait 200 MEMCLKs. If executing pass 2, wait 32 MEMCLKs. */
	pMCTData->AgesaDelay(140);
	/* Program F2x[1, 0]9C_x08[WrtLevelTrEn]=0. */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 0);
	/* Read from registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52
	 * to get the gross and fine delay settings
	 * for the target DIMM and save these values. */
	ByteLane = 0;
	while (ByteLane < MAX_BYTE_LANES)
	{
		getWLByteDelay(pDCTData,ByteLane, dimm);
		setWLByteDelay(pDCTData,ByteLane, dimm, 1);
		ByteLane++;
	}

	/* 6. Configure DRAM Phy Control Register so that the phy stops driving
	 *    write levelization ODT. */
	set_DCT_ADDR_Bits(pDCTData, pDCTData->DctTrain, pDCTData->NodeId, FUN_DCT,
			DRAM_ADD_DCT_PHY_CONTROL_REG, WrLvOdtEn, WrLvOdtEn, 0);

	/* Wait 10 MEMCLKs to allow for ODT signal settling. */
	pMCTData->AgesaDelay(10);

	/* 7. Program the target DIMM back to normal operation by configuring
	 * the following (See section 2.8.5.4.1.1
	 * [Phy Assisted Write Levelization] on page 97 pass 1, step #2):
	 * Configure all ranks of the target DIMM for normal operation.
	 * Enable the output drivers of all ranks of the target DIMM.
	 * For a two DIMM system, program the Rtt value for the target DIMM
	 * to the normal operating termination:
	 */
	prepareDimms(pMCTData, pDCTData,dimm,FALSE);
}