Beispiel #1
0
/*-----------------------------------------------------------------------------
 *  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 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 - 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);
		}
	}
}
Beispiel #2
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);
}